Update: Found a solution! Using chrome developer tools, I've found that the problem is hardcoding src files in /Applications/blahblah. It's looking for the files in localhost/Applications/blahblah. For now, I've copied the .js files it needed in a subdirectory to /Library/WebServer/Documents/ (where localhost seems to start from on my machine) and coded a path to there. Thanks for the help!
Newbie to PHP here. Can't find my answer with some thorough googling and lots of trying to debug myself.
I'm doing everything locally on my own machine.
I have a PHP class which builds an string that makes up an html page in its entirety, then returns it. My index.php script creates an instance of this class and calls the function that returns the html, and echos it the return. When I execute this class, the page comes up blank (using chrome as a browser). When I "view source" on the blank page, I see exactly the html script I had intended to view.
If I copy and paste that html script into a new file, blahblah.html and load blahblah.html directly with chrome, it works just fine.
Possible subtlety: the html string includes a javascript function which pulls from a hard-coded src directory on my machine.
Thanks for the help! Let me know what more information I might provide that could help.
EDIT: Here's the code:
index.php:
<?php
function __autoload($class_name)
{
$source = '/Path/To/src/' . $class_name . '.php';
if (file_exists($source)) require $source;
else throw new Exception('class "' . $class_name . '" source file not found. Failed to autoload...');
}
$myweb=new GenHCSplineIrregTime();
echo $myweb->genWeb();
?>
GenHCSplineIrregTime.php:
<?php
class GenHCSplineIrregTime
{
public function __construct()
{
;
}
public function __destruct()
{
;
}
public function genWeb()
{
return $this->genEntireHTMLFile();
}
private function genEntireHTMLFile()
{
$cont="";
// $cont = $cont . "<!DOCTYPE HTML>\n";
$cont = $cont . "<HTML>\n<head>\n";
$cont = $cont . "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n";
$cont = $cont . "<title>This is my title</title>\n";
$cont = $cont . "<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js\"></script>\n";
$cont = $cont . "<style type=\"text/css\">\n\${demo.css}\n</style>\n";
$cont = $cont . "<script type=\"text/javascript\">\n";
$cont = $cont . "\$(function () {\n\n$('#container').highcharts({\nchart: {\ntype: 'spline'\n},\n title: {\ntext: 'BATTERY SHIT'\n},\nsubtitle: {\ntext: 'Irregular time data in Highcharts JS'\n},\n";
$cont= $cont . "xAxis: {\ntype: 'datetime',\ndateTimeLabelFormats: {\nmonth: '%e. %b',\nyear: '%b'\n},\ntitle: {\ntext: 'Date'\n}\n},\n";
$cont= $cont . "yAxis: {\ntitle: {\ntext: 'Snow depth (m)'\n},\nmin: 0\n},\ntooltip: {\nheaderFormat: '<b>{series.name}</b><br>',\npointFormat: '{point.x:%e. %b}: {point.y:.2f} m'\n},\n";
//data starts here
$cont= $cont . "series: [{\nname: 'Winter 2007-2008',\ndata: [\n";
$cont= $cont . "[Date.UTC(1970, 9, 27), 0 ],\n";
$cont= $cont . "[Date.UTC(1970, 10, 10), 0.6 ],\n";
$cont= $cont . "[Date.UTC(1970, 10, 18), 0.7 ]\n]\n}]\n";
$cont= $cont . "});\n});\n";
$cont= $cont . "</script>\n</head>\n<body>\n";
$cont= $cont . "<script src=\"/Applications/BasicSoftware/Highcharts-4.0.3/js/highcharts.js\"></script>\n";
$cont= $cont . "<script src=\"/Applications/BasicSoftware/Highcharts-4.0.3/js/modules/exporting.js\"></script>\n";
$cont= $cont . "<div id=\"container\" style=\"min-width: 310px; height: 400px; margin: 0 auto\"></div>\n";
$cont= $cont . "</body>\n</html>\n";
return $cont;
}
private function fetchData()
{
$data="";
return $data;
}
}
?>
This happens because PHP is a server-sided scripting language, not a client-sided one like HTML. It needs a server to run on. To have a web server on your computer, you'll need software like WampServer or XAMPP. Once you have these installed, you can use PHP.
UPDATE: Your code outputs nothing because the GenHCSplineIrregTime class is not imported correctly. You will need to use the require or include (or require_once, include_once, depends on what you need) statements to add GenHCSplineIrregTime.php, but not the way you did it. You did what some old manuals show:
//foo.php
<?php
class foo {
public function __construct() {
echo "hi";
}
}
?>
//index.php
<?php
function __autoload($classname) {
$filename = "./". $classname .".php";
include_once($filename);
}
$obj = new foo();
?>
Problem is, what's $classname? The code is incomplete; it will just load nothing, really, or some irrelevant file. That's why, instead, you'll almost always see:
//index.php
<?php
require 'foo.php';
$obj = new foo();
?>
UPDATE 2: I am glad that your problem was resolved but for next time, pay special attention to the title of the page, which was changed (because everything but the Javascript part of the HTML worked). Hence, it wasn't a completely blank page as you implied (i.e. no HTML compiled).
if you have your html code in a string, let say $str, all you need is to print the content of the string just like this :
$str "<h1> Hello world ! </h1>";
echo $str;
If your html code is inside another page , all you need to do is to load the content of your page inside a string and print it :
$str = file_get_contents("path_to/blahblah.html");
echo $str;
PHP only runs on a server.
Download XAMPP and run apache server.
After you downloaded and installed it, go to the xampp folder, and to htdocs folder and put your php file in there.
And navigate to where your php file is located, for example: localhost:/index.php.
Then your php code should run properly.
Well if you're viewing the HTML in the source then you know that the HTML string is being printed. So maybe you're doing something with headers? Possibly Chrome doesn't expect to receive HTML content when you print it from PHP, but when you take the same content and put it into a file with .html extension it's a no-brainer, so it renders it automatically. Try opening up the Chrome's dev tools, reload the page and look under 'network' to see what headers you're receiving.
If you are in fact printing the html string, as you've verified in the 'source' received by the client (chrome) then you know your php code was evaluated. Given that as true, and without trying to guess at what is going on with the js script, that is the only thing I can think of.
Related
I have a project whose requirements have been consistently expanding. At first, it was fine because I could hard code most of it. However, I find that I am making different versions of the same type of forms and programming specific JS files to go along with them. Is there a way to dynamically create an HTML and JS file? So, maybe I could write a function or something that reads requirements from a text files, and from that, build an HTML file, a JavaScript file, and modify other JavaScript files within the directory. For example:
Say I have a JS file named main.js
/* I hold all the basic requirements and functions for every form*/
var blueForm = ...
var redForm = ...
There currently exists HTML files named blueForm.html and redForm.html.
I want to add a function to main.js such that:
function createNewForm(requirements){
. . .
createHTML();
createJS();
modifyMain(this); /* as in this file (main.js) */
. . .
if(successful){ return 0; }
return 1;
}
Now main.js should have been modified like:
var blueForm = ...
var redForm = ...
var greenForm = ...
And now there exists HTML files named blueForm.html, redForm.html, and greenForm.html.
The answer is yes. The most accessible way of doing this is using php, most commonly implemented through a Linux / Apache / MySQL / PHP stack (LAMP). HTML and JS be easily injected into a file your browser reads as html.
Here's a sample.php file:
<html>
<body>
<?php
echo "Hello World";
echo "<script>";
$myvar = 1;
if ($myvar==1) {
echo "function dosomethingjavascripty() {";
echo "console.log('doing it');";
echo "}";
}
echo "</script>";
?>
</html>
</body>
I have a PHP variable that I am declaring upon loading the page, and want to use it in a JavaScript/jQuery function that loads upon a button click.
I have the following on my index.php page:
// Creating a random name for a file and creating it. Working properly.
$fname = substr(md5(rand()), 0, 7);
$file = fopen("temp/" .$fname, 'w');
And when I click a button, the following JavaScript function should run:
//Use the generated filename in the JavaScript function
var fname = <?php echo $fname; ?>;
var fileName = "temp/" + fname;
My understanding is that the PHP variable is outside of the scope of the JavaScript function, since I believe this is the way it should be done.
Can you please help with this?
PHP generates a page and presents it to a browser. As far as the browser is concerned, by the time the page is received, PHP is finished. So to answer your question, that should work, since PHP will essentially just spit out the text on to the page, which will act as normal. That is, unless I am terribly misinformed.
The "scope" of a PHP variable is long gone by the time Javascript gets to run, so that isn't really an issue.
Try do this. in a php file of course.
var fname = '<?php echo $fname; ?>';
I think you need an extension on your filename:
$extension = ".txt";
$fname = substr(md5(rand()), 0, 7).$extension;
$file = fopen("temp/" .$fname, 'w');
The problem is the missing apostroph like anant kumar singh mentioned.
I tested the following code in a webpage:
<?php
$fname = substr(md5(rand()), 0, 7);
$file = fopen("temp/" .$fname, 'w');
?>
<html>
<head
</head>
<body>
<script>
var fname = "<?php echo $fname; ?>";
var fileName = "temp/" + fname;
</script>
</body>
</html>
This function worked previously (the last time I opened this project over a week ago), but now I can't seem to get it to work at all and I have no idea how to figure out what's going wrong! First, I'll diagram my file architecture in case my file paths are incorrect and causing my php to not even be called:
~/Sites
proj1
htdocs
index.html
ajax.php
scripts
java_script.js
styles
style_sheet.css
includes
scrapedImages
.
.
.
Here's the JS function that uses AJAX to call a .php script:
function requestServer() {
$.getJSON('/Users/aweeeezy/Sites/proj1/htdocs/ajax.php', function(data) {
$.each(data, function(key, val) {
var html = "<img src='/Users/aweeeezy/Sites/proj1/includes/scrapedImages/"+val+"' style='display:block;max-width:20px;max-height:20px;width:auto;height:auto' alt=null />"
$('#puppy-box').prepend(html);
});
});
}
The line setting var html was <img src='...'+images[i]+"... when I first opened the project this morning, but I'm not sure why...I think because I was testing the site out, it was faster to only load a fraction of the images and used a for loop to cycle through only the first 10 or so pictures, hence the i index. Anyway, shouldn't it be data[i], or val[i]...or data[val]? I have no idea what's going on here.
Here's the ajax.php file that the JS function is trying to call:
<?php
$images = scandir('/Users/aweeeezy/Sites/proj1/includes/scrapedImages/');
/*foreach ($images as $key => $image) {
if ($image == '.' || $image == '..') {
unset($images[$key]);
}
}*/
echo json_encode($images);
?>
I commented out the middle part because I wasn't sure if this was causing a complication. I tried putting both echo and print lines in here to see if the script is being called, but even if they are working, I can't really see them because they're being returned as data (I think) to the JS function that calls the script.
How do I even go about debugging this mess and get my girlfriend's valentine's day project back on track!
I am working on a PHP project which writes js files and executes them on page load.
Is it a good practice to write JS file dynamically and append the script tag to the page html and execute it only every page request?
Here is my working creating and linking the JS File:
<?php
if (!function_exists('setScript')) {
function setScript($script = null)
{
static $_script = array();
if ($script == null) {
return $_script;
$_script = array();
} else {
$_script[] = $script;
}
}
}
if (!function_exists('linkJs')) {
function linkJs($controllerName, $actionName)
{
$jsFileName = randomString(40) . '.js';
$folderName = PUBLIC_DIR . DS . 'generated';
if (!is_dir($folderName)) {
mkdir($folderName);
chmod($folderName, 777);
}
$fileName = $folderName . DS . $jsFileName;
$availableFiles = scandir($folderName);
unset($availableFiles[0]);
unset($availableFiles[1]);
foreach ($availableFiles as $file) {
$file = $folderName . DS . $file;
if (is_file($file)) unlink($file);
}
$script = "$(document).ready(function() {\n" . implode("\n", setScript()) . "});";
file_put_contents($fileName, $script);
$url = loadClass('Url', 'helpers');
return "<script type='text/javascript' src='" . $url->baseUrl() . 'public/generated/' . $jsFileName . "'></script>";
}
}
if (!function_exists('alert')) {
function alert($message, $returnScript = false)
{
if (isAjax()) {
if ($returnScript) {
return "\nalert('$message');\n";
}
echo "\nalert('$message');\n";
} else {
setScript("\nalert('$message');\n");
}
}
}
Please suggest if this is a good practice in doing so or any other way i can do it.
Approx 30-40 users would be logged in to the website concurrently and would have approx 5-10 page requests per second. (These are projections. Might go high).
is writing js file (to the hard drive) and linking it is a good practice or just adding the raw scripts to the html body is a good practice since writing to js file gets the js to be un-intrusive.
Also, the javascript generated is going to be dynamic, probably for every page request.
If you can see no other choice than dynamically generating every time (my guess is that the content of the script is at least 80% different for each request) then write the script directly into the html file as linking will cause the browser to make another request to include the script.
You are already going to have degraded performance by dynamically generating the file.
The best way of doing this that I can think of is to actually create a php script that generates the js by itself and then create a .htaccess rewrite rule to rewrite /script/generator/{HASH_FOR_REQUEST}.js to /path/to/php-script-generator.php so that you can leverage browser caching if the request is the same.
However, if it is only specific details about the JS that change and the js functions body remains pretty similar (ie, you are using the js to report info back to the client) then consider writing the js in a php file and then using php inline tags to echo the stuff you need to change.
For example:
This script will write an alert to the js so then when loaded with a query string it will report back what is in the query...
<?php
// disable output buffering
/* the reason for this is that the browser will wait
* for the first byte returned before continuing with the page.
* If it has to wait for the whole file performance will be degarded.
*/
while(ob_get_level() != 0) ob_end_clean();
header("Content-type:text/javascript");
// it is wise to set some cache headers here
if(isset($_GET['message']) {
$message = urldecode($_GET['message']);
} else {
$message = "No message!";
}
?>
// write the js...
alert("<?php echo $message; ?>");
By requesting /path/to/script.php?message=hello+world the script will return alert("hello world");
I tried to output a simple ping command on a web page in a similar way( and same time) as it is displaying in terminal, using shell_exec; But it is displaying only after the complete execution, while I needed it to display whenever it is displaying on terminal, My code is
<?php
$i= shell_exec("ping -c 4 google.com");
echo "<pre> $i <pre>";
?>
It is waiting for a while and the dumping the whole thing on a single shot.. can PHP recognize the outputting of each line and display it on the web page
EDIT I tried this also
<?php
$proc = popen("ping -c 4 google.com", 'r');
echo '<pre>';
while (!feof($proc)) {
echo fread($proc, 4096);
}
echo '</pre>';
?>
But still I gets the same result..
EDIT When I tried to execute this PHP code in terminal , ( php test.php) it is working properly in the same way it gives when we directly do ping on server. but in web page it is still the same.
Uhm, strange behavior from the web browser. I'm using this code:
<?php
ob_end_flush();
ini_set("output_buffering", "0");
ob_implicit_flush(true);
function pingtest()
{
$proc = popen("ping -c 5 google.com", 'r');
while (!feof($proc))
{
echo "[".date("i:s")."] ".fread($proc, 4096);
}
}
?>
<!DOCTYPE html>
<html>
<body>
<pre>
Immediate output:
<?php
pingtest();
?>
</pre>
</body>
</html>
In the browser the content appears after all bytes has been received.
But, the content is actually delivered on time, do this test:
wget -O - -q "http://localhost/ping.php"
You will see that the response is delivered by php & apache2 on time.
I'm using this kind of execution on long task for a while, but using a more complex solution:
an html file for interface
a php file that run the long task
Connect html interface with php long execution using EventSource object (available on html5)
interface (test.html)
<!DOCTYPE html>
<html>
<head>
<title>Simple EventSource example</title>
</head>
<body>
<script type="text/javascript">
function eventsourcetest() {
var ta = document.getElementById('output');
var source = new EventSource('test.php');
source.addEventListener('message', function(e) {
if (e.data !== '') {
ta.value += e.data + '\n';
}
}, false);
source.addEventListener('error', function(e) {
source.close();
}, false);
}
</script>
<p>Output:<br/><textarea id="output" style="width: 80%; height: 25em;"></textarea></p>
<p><button type="button" onclick="eventsourcetest();">ping google.com</button>
</html>
Server Side Component (test.php)
<?php
ob_end_flush();
ini_set("output_buffering", "0");
ob_implicit_flush(true);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
function echoEvent($datatext) {
echo "data: ".implode("\ndata: ", explode("\n", $datatext))."\n\n";
}
echoEvent("Start!");
$proc = popen("ping -c 5 google.com", 'r');
while (!feof($proc)) {
echoEvent(fread($proc, 4096));
}
echoEvent("Finish!");
Put both files in one place on a webserver and enter test.html, I think this is what you are looking for from the beginning.
Use output buffering and flush. You might also want to look into the Symfony 2 process component.
Its not a PHP matter, or rather its a shared matter between php and the browser.
In PHP: Make sure output buffering is off, you can do this by running ob_end_clean() before outputting anything.
As this SO post suggests you have to either pad the very first string outputted to 512 bytes OR specify a charset encoding via http header. The padding solution may very well be the easiest way around this, its basically this: echo(str_pad("Live Ping Test!",512)); and then start echoing the result of your fread.
You might want to try using flush() to flush the output as and when its ready, and use passthru() to execute the command.
Carlos C Soto is right, you have to use javascript. EventSource is the way to go. Basically, it's javascript code that will constantly call a url
You can write the output of ping in a file, and write a php script that will read the last line, then call this script with eventsource.
Search "Server Sent Events" on the web to find more examples
if can resolve using apache execution user. if your root user is diffrent and server user different then it will not allow to execute command line command.
I tested Carlos's answer on my side...
and I HAD to add flush();ob_flush(); for it to work properly (both needed flush AND ob_flush)
like this
<?php
$proc = popen("ping -c 5 google.com", 'r');
while (!feof($proc))
{
echo "[".date("i:s")."] ".fread($proc, 4096).'<br>';flush();ob_flush();
}
?>