I am new to Web Development. I'm creating a web application where I need to use ZMQ Library for receiving data continuously and update a html table in real-time.
I tried a lot and just succeeded in receiving a single data packet. Later I'm calling the function recursively to get all data packets. But, by the time I call the function, I already lost some packets in the gap.
Following is the javascript function I'm using in index.php and test.php for receiving data using ZMQ:
Javascript function inside index.php
function samp(result)
{
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var x=document.getElementById('PageTable');
var rowCount = document.getElementById("PageTable").rows.length;
for (var i = 0; i < rowCount; i++)
{
if(x.rows[i].cells[2].innerHTML == xmlhttp.responseText)
{
x.rows[i].cells[3].innerHTML=xmlhttp.responseText;
}
}
samp(result);
}
};
xmlhttp.open("GET","test.php?q="+result,true);
xmlhttp.send();
}
test.php for receiving data using ZMQ
<?php
$Params = $_REQUEST["q"];
$context = new ZMQContext();
$subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB);
$subscriber->connect("tcp://localhost:5000");
$mnemonic = explode(" ", $Params);
foreach ($mnemonic as $value)
{
if($value!="")
{
$subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $value);
}
}
$contents = $subscriber->recv();
echo $contents;
I even tried running the php script inside the javascript function but had no luck. I also tried using an infinite loop in test.php to receive data as following but now as the loop is not ended I stopped receiving even a single packet.
while(true)
{
$contents = $subscriber->recv();
echo $contents;
}
Any help to solve this problem or even suggestion to any different approach is highly appreciated. Thank you.
Related
I need to use a powershell script within my PHP code. Javascript code calls a PHP file and waits for the response, the PHP code calls my powershell script and returns a value.
This works fine when I run PHP alone which calls powershell script.
This also works fine when I simply print a value in runpm.php commenting shell_exec() command. So I assume the problem is with the Shell_exec() command. Any help would be really appreciated. Thanks in Advance.
javascript code:
var myLink = document.getElementById('btn');
var php_var = "<?php echo $dest_path; ?>";
myLink.onclick = function(){
try{
var pingtext = document.getElementById('ping');
var ping = document.getElementById('btn');
ping.style.backgroundColor = "#5bc0de";
ping.style.visibility='hidden';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText == 1) {
alert(this.responseText);
ping.style.visibility='visible';
ping.style.backgroundColor = "green";
ping.innerHTML='Import Success' ;
ping.style.width='80px';
ping.style.marginLeft='10%';
pingtext.innerHTML = '';
} else {
alert("error");
ping.style.visibility='visible';
ping.style.display='block';
ping.style.backgroundColor = "red";
ping.innerHTML='Failed' ;
ping.style.width='80px';
ping.style.marginLeft='25%';
pingtext.innerHTML = '';
}
}
};
pingtext.innerHTML = "<img src=\"gentel/production/images/loadingspinner.gif\" width=\"30px\">";
xmlhttp.open("Get", "runpm.php", true);
xmlhttp.send();
}catch(e){
console.error(e);
}
runpm.php:
<?php
$psoutput = shell_exec('powershell -ExecutionPolicy Bypass -NoProfile -File "C:\inetpub\wwwroot\retailPlanning\testpsscript.ps1"');
echo "$psoutput"
?>
testpsscript.ps1:
cls
echo "1"
What the web server do you use?
If it is Apache, you can try to run this service as non-default user. To do it go to services.msc, find Apache service, click Properties, find Log On tab and set some other account (username and password). Do not forget to restart service.
If it is not Apache, you can try to do similar steps with any other web server.
I have a general info form. When I click on submit, all values are got using javascript and send it to PHP function using ajax.
The PHP function validates the form and returns
EITHER form errors as an array
OR successful message.
I want to get the array generated by PHP on ajax side and pass it to the form to display the errors on respective form fields.
I have successfully generated the array of errors in PHP.
print_r($arrayname) shows all the values as an array.
But I don't want to show instead I want to pass it to ajax and retrieve the array in a div and do work on that array.
--------- AJAX ------
function general()
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('POST','addGeneral',true);
var data = new FormData();
data.append('title',document.getElementById('title').value);
data.append('firstname',document.getElementById('firstname').value);
data.append('middlename',document.getElementById('middlename').value);
data.append('surname',document.getElementById('surname').value);
xmlHttp.send(data);
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState==4)
{
var status = xmlHttp.responseText;
document.getElementById('responseG').style.display="block";
if(status=='true')
{
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else
{
document.getElementById('responseG').className="alert alert-danger";
document.getElementById('responseG').innerHTML=status;
}
}
}
}
---- PHP FUNCTION ---
public function addGeneral()
{
$status=array();
extract($_POST);
$this->form_validation->set_rules('title','Title','required',array('required' => 'You must provide a %s.'));
$this->form_validation->set_rules('firstname','First Name','required');
$this->form_validation->set_rules('middlename','Middle Name','required');
$this->form_validation->set_rules('surname','Surname','required');
if($this->form_validation->run()===FALSE)
{
$status=$this->form_validation->error_array();
}else
{
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
$this->Manage_employee_model->update_employee($data);
$status=array('true');
}
}
Once a PHP script finished running and the browser receives the end of the HTML response, it's over, you can't directly modify the output already sent with more PHP. What you can do it use AJAX to get the data and render it on the client side using JS, or render it on the server side and just inject the result with JS.
Client rendering
For this you just need your PHP script to return the data, then loop over it and append each item to your div in JS. It's a bit awkward to render things with native JS but this approach keeps the presentation in one place instead of having HTML code on your backend.
Server side
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
echo json_encode($data);
Client side
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4) {
var data = JSON.parse(xmlHttp.responseText);
document.getElementById('responseG').style.display="block";
if(data.status=='true') {
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else {
document.getElementById('responseG').className="alert alert-danger";
for(var i = 0; i < data.length; i++){
document.getElementById('responseG').innerHTML+= '<p>'+data[i]+'</p>;
}
}
}
}
Server rendering
Here we use PHP to generate the HTML string on the backend, send it back via AJAX and just append it to the div on the client side. The disadvantage here is mixing HTML templates with your backend code.
Server side
$data=array(
'title'=>$title,
'firstname'=>$firstname,
'middlename'=>$middlename,
'surname'=>$surname
);
$html = '';
foreach ($data as $key => $item) {
$html += '<p>'.$item.'</p>';
}
echo json_encode(array('html' => $html));
Client side
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState==4) {
var data = JSON.parse(xmlHttp.responseText);
document.getElementById('responseG').style.display="block";
if(data.status=='true') {
document.getElementById('responseG').className="alert alert-success";
document.getElementById('responseG').innerHTML="<p>Successfully Updated</p>";
}
else {
document.getElementById('responseG').className="alert alert-danger";
document.getElementById('responseG').innerHTML = data.html;
}
}
}
In your php code after you have done all the checks and populated your response array just do a simple echo to return that data to ajax.
Example in php: echo json_encode($status);
The best place to put this code is under your if statement
Print error message on form
<?php
if(!empty(validation_errors())) {echo
validation_errors();}
?>
Current setting:
In the same PHP document I have a PHP randomizer function and the HTML that calls that function -- a separate txt document with strings that are called by the php function:
Function
<?php
function rand_line($fileName, $maxLineLength = 4096) {
$handle = #fopen($fileName, "strings.txt");
if ($handle) {
$random_line = null;
$line = null;
$count = 0;
while (($line = fgets($handle, $maxLineLength)) !== false) {
$count++;
if(rand() % $count == 0) {
$random_line = $line;
}
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
fclose($handle);
return null;
} else {
fclose($handle);
}
return $random_line;
}
}
?>
I call the function in the HTML using:
<?php echo rand_line("strings.txt");?>
<input type="button" value="Another String" onClick="window.location.reload()">
This tends to be slow when multiple users access the page and press the button to obtain a new status.
What I would like to achieve:
Improve the performance and make the whole thing not so heavy: maybe the randomizer is unnecessarily complicated and I could work with AJAX calls for example, but if possible keeping the string list inside the strings.txt file and separated from the PHP script and HTML.
Sorry if I don't know what I'm talking about... I'm not a proficient programmer. Just a guy that hacks stuff together once in a while :)
You really don't want to use window.location.reload();
That is terrible... You do not want to refresh a page...
location.reload() sends http request for a whole new page (whole HTML), and then not only that your browser needs to render whole HTML again, you have to transfer more duplicated data through a network, from point A to point B.
You should send HTTP request only for a data that you need (you don't need whole HTML again, you loaded it the 1st time you visited page).
Instead, use XMLHttpRequest javascript library (AJAX) to request only for a portion of data (in your case => random line string)
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
<script type="text/javascript">
function loadDoc(url, cfunc) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
cfunc(xhttp);
}
};
xhttp.open("GET", url, true)
xhttp.send();
}
function randomLine(xhttp) {
alert(xhttp.responseText);
}
</script>
</head>
<body>
<input type="button" value="Get random line" onClick="loadDoc('http://localhost:8080/myScript.php', randomLine)">
</body>
</html>
PHP:
myScript.php
<?php
function rand_line($fileName, $maxLineLength = 4096)
{
...
}
echo rand_line("strings.txt");
?>
*EDIT #2*
Fully-functioning script. Grabs initial strings via PHP, and stores in array for later JavaScript usage. Minimizes # of calls.
PHP to grab strings from file; generates a default (random) string, as well as an array of strings for later use with button.
/**
* #input array $file
* #return array (mixed) [0] => string, [1] => array
*/
$randomStringFromFile = function($file) {
if (!$file) return false;
/**
* #return Removes carriage returns from the file
* and wraps $val with single-quotes so as
* to not break JavaScript
*/
$add_quotes = function(&$val) {
return str_replace("\n", "", "'$val'");
};
return [$file[rand(0, count($file)-1)], array_map($add_quotes, $file)];
};
$randomString = $randomStringFromFile( #file('strings.txt') ) ?: false;
JavaScript
<div id="string_container"><?php echo $randomString[0]; // defaults random string to page ?></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var arr = [<?php echo implode(',', $randomString[1]); ?>],
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length)];
};
</script>
Place the above in your page and you should be good to go.
EDIT (ORIGINAL)
We can remove PHP from the equation entirely using the following (fastest method):
<div id="string_container"></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var request = new XMLHttpRequest(),
file = 'strings.txt';
request.open('GET', file);
request.onload = function() {
if (request.status === 200) {
var arr = request.responseText.split("\n"), /** assuming line breaks in file are standard carriage returns (Unix); "\r" if Windows */
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length-1)];
}
};
request.send();
};
</script>
ORIGINAL w/PHP
We can simplify the PHP even further, removing loops from the equation altogether.
$randomStringFromFile = function($file) {
if (!$file) return false;
return $file[rand(0, count($file)-1)];
};
echo $randomStringFromFile( #file('strings.txt') ) ?: 'No worky!';
Using file() will return the contents in an array, thus allowing you to simply select a key at random and return the value.
NOTE On average, $file[rand(0, count($file)-1)] outperformed array_rand() (E.g. $file[array_rand($file)];) when selecting a key at random. By negligible amounts, have you.. ~0.0002s vs ~0.0005s, respectively.
You can simplify your code
function rand_line($fileName, $maxLineLength = 4096) {
$f = file($fileName);
$length = $maxLineLength + 1;
do {
$line = $f[array_rand($f)];
$length = strlen($line);
} while ($length > $maxLineLength);
return $line;
}
In the website EasyNote I have got a problem with newlines.
On body onload I set a timer for auto-uploading a note every 3 seconds like this:
<body onload="setInterval(uploadNote,3000);current = 1;">
And the code for uploadNote is:
function uploadNote() {
var note = current+document.getElementById(\'note\').value; //current is the number of the note selected\' because echoed
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){}
}
xmlhttp.open("GET","uploadnote.php?q="+note,true);
xmlhttp.send();
}
And then there is this php-code:
$note = $_GET["q"]; //contains both notenumber as first digit and note
echo($note."\n"); //for debugging reasons
$notenumber = substr($note, 0, 1);
$notecontent = substr($note, 1, strlen($note));
$notecontent = str_replace("'","''",$notecontent);
$notecontent = nl2br($notecontent);
echo($notecontent); //for debugging reasons
$request = 'UPDATE notes SET note'.$notenumber.' = "'.$notecontent.'" WHERE mail LIKE "'.$email.'"';
$result = mysql_query($request);
Now, the problem is, that the newline characters in the textarea are erased completely, so the result of the php-snippet is twice the text without newlines and in the database also.
However, there is no problem showing newlines in the textarea when I insert them directly in the database.
Help would be greatly appreciated.
EDIT:
updated uploadNote() function:
function uploadNote() {
var note = current+document.getElementById(\'note\').value;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){}
}
xmlhttp.open("POST","uploadnote.php",true);
xmlhttp.send("note="+note);
}
and php:
$note = $_POST["note"];
echo($note."\n");
$notenumber = substr($note, 0, 1);
$notecontent = substr($note, 1, strlen($note));
$notecontent = mysql_real_escape_string($notecontent);
echo($notecontent);
$request = 'UPDATE notes SET note'.$notenumber.' = "'.$notecontent.'" WHERE mail LIKE "'.$email.'"';
$result = mysql_query($request);
Problem now is that nothing works. The note won't update in the MySQL db.
The problems with your code:
Don't use a GET request for something that changes things on the server, use POST.
Database queries need the variable parts escaped. Use mysql_real_escape_string() on the value that is written to SQL.
Do not use any html-centric formatting when saving data to the database. You can use it when outputting the code back to the browser.
Inside a textarea, you are not allowed to use any HTML markup, so using <br> for a newline is wrong.
I have a script (javascript) that works in firefox but not in chrome or IE. I opened chromes debug console to find the problem. No errors are reported and the code works perfectly. Running it again with the console closed does not work again.
I verified that the version of the script is correct (not old and cached). The console does not report any warnings or errors.
I tried putting in simple logging that writes to a div at the bottom of the page - no information.
(in the debug console it works - including logging info in the div).
The function is the callback after an XMLHttpRequest is made to the server.
I verified that the php script is called by including error_log calls. The error_log shows the return value correctly. A page refresh also show the row has been deleted.
It appears as if the function removeRow() is never called unless the console is open. (method or reserved words conflict??) Tried changing the function name to delRow (including callback) - still not working.
All other Ajax calls seem to work fine.
A Code snippet follows:
var pos = 0;
var xhr;
function eraseRow() {
var myImage = this;
var fullid = myImage.id;
// split row no and record id eg 5_1223 => row=5 and recordid=1223
var idComponents = fullid.split("_");
if (idComponents.length > 1) { // check if image has complete row info
rowid = idComponents[1]; // extract row number from id
pos = parseInt(idComponents[0]);
xhr = new XMLHttpRequest(); // only support IE8 or +
xhr.onreadystatechange = removeRow;
xhr.open("GET","valid_del.php$delrow="+rowid;
xhr.send(null);
}
}
function removeRow() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var err = document.getElementById("errormsg");
var str = xhr.responseText;
err.innerHTML = "Server returned "+str;
if (str === "go-ahead") {
var table = document.getElementById("tableid");
table.deleteRow(pos);
}
}
}
}
PHP (valid_del.php):
<?php
include(funclib.php);
if (isset($_GET['delrow']) && strlen($_GET['delrow'] > 0) {
$recid = $_GET['delrow'];
$db = createDbConn(); // function that connects to mysql server db
$result = $db->query("delete from doclibrary where doc_id='$recid'");
if ($result===true) {
echo 'go-ahead';
error_log('Script successful - returns go-ahead',0);
} else {
echo 'stop';
error_log('Script not successful - returns stop',0);
}
$db->close();
} else {
echo 'stop';
error_log('Script not given record id - returns stop',0);
}
?>
I think the DOM is not ready, try to add your code calls into window.onload, or in $(document).ready if you are using JQuery.