Page 1 of 1

Asynchronous surprises

PostPosted: Thu Feb 06, 2020 6:06 am
by John Robin Dove
Hi Clifton,

This has probably more to do with php than Powerpac but I would be grateful for your help. I need to save a file with several hundred characters on the server and then empty the array that was used to create the file to start a new project. The return from the server is an integer corresponding to the number of characters. I imagined that if I waited for the callback from the server before emptying the array there would be no problem. Surprisingly the array gets emptied before the file is saved! I can't understand how this happens. Any suggestions please?

I am now using a 'time-switch' like this:

if (isNaN(e.data))
{
alert("ERROR:" + "\n" + e.data);
}
else
{
if (sharedActions.newProject == true)
{
  var fct = function()
  {
  sharedActions.newProject1();
  }
setTimeout(fct, 500);
}
}

but I'm not convinced it will always solve the problem.
John

PS here is the php file I'm using:

<?php
$serverPath=$_SERVER['DOCUMENT_ROOT'].'/programs';
if (isset($_POST['endPath']))
{
$endPath=$_POST['endPath'];
if (isset($_POST['mydata'])) {
echo file_put_contents($serverPath.$endPath, $_POST['mydata']);
// If the return value is more than 0, presumably the file has been written.
}
else
{
echo 'notSet';
}
}
else
{
echo 'notSet';
}


UPDATE
I have now added the LOCK_EX parameter to the file_put_contents line in the php file and I think it does the trick but could you confirm this please?
?>

Re: Asynchronous surprises

PostPosted: Thu Feb 06, 2020 9:02 am
by Clifton
I would start by making this modification to your PHP code:
<?php
$rtn = 0;
$serverPath=$_SERVER['DOCUMENT_ROOT'].'/programs';
if (isset($_POST['endPath'])) $endPath=$_POST['endPath'];
if (isset($_POST['mydata']) && isset($endPath)) {
$rtn = file_put_contents($serverPath.$endPath, $_POST['mydata']);
// If the return value is more than 0, presumably the file has been written.
}
exit($rtn); //$rtn will be an integer 0 or false if problem occurs and a value > 0 on success

The use of echo doesn't really do anything until the script ends, so it is usually better to make sure PHP has finished before allowing the client to do whatever is next in the process.

Re: Asynchronous surprises

PostPosted: Thu Feb 06, 2020 10:06 am
by John Robin Dove
Thanks very much. I have amended my php file and I will try to apply this to some others that I use.

Re: Asynchronous surprises

PostPosted: Thu Feb 06, 2020 10:45 am
by John Robin Dove
Tried to apply your system to another php file but failed miserably so, if you have time, perhaps you could improve this one?

<?php
$serverPath=$_SERVER['DOCUMENT_ROOT'].'/programs/';
if ( isset($_POST['endPath']) )
{
$endPath=$_POST['endPath'];
if (!file_exists($serverPath.$endPath))
{
$err= mkdir($serverPath.$endPath, 0777, true);
if ($err == 1)
{
echo 'OK';
}
}
else
{
echo 'OK';
}
}
else
{
echo "notSet";
}
?>


Thanks.
John

Re: Asynchronous surprises

PostPosted: Thu Feb 06, 2020 3:00 pm
by Clifton
Perhaps, something like this: (untested)
    $rtn = 1; //Set default to return true
$serverPath = $_SERVER['DOCUMENT_ROOT'] . '/programs/';
if ( isset($_POST['endPath']) ) {
$endPath = $_POST['endPath'];
if ( !file_exists($serverPath.$endPath) ) {
$rtn = mkdir($serverPath.$endPath, 0777, true); //$rtn may be true or false
}
} else {
$rtn = 0; //Failure to provide valid $_POST forces return as false
}
exit( "$rtn" );

Re: Asynchronous surprises

PostPosted: Fri Feb 07, 2020 4:52 am
by John Robin Dove
Thank you very much. That one works perfectly. 1 for success and 0 for failure. I had a bit of trouble making it fail and made quite a lot of silly directories! :) I needed a definitive return like this because making a new directory is a link in a chain of tasks to be completed when a new exercise is created.
John

Re: Asynchronous surprises

PostPosted: Sat Feb 08, 2020 5:21 am
by John Robin Dove
Hi Clifton,
I'm a bit confused. I thought the php was returning 0 or 1 because that's what you see if you add alert(e.data). But in fact it is actually true/false. :o How come? Please forgive my ignorance.
John

Re: Asynchronous surprises

PostPosted: Sat Feb 08, 2020 9:10 am
by Clifton
PHP is its own language. So when returning true/false back to the client, it can be a little inconsistent. JavaScript often interprets PHP's boolean values as 1 or 0, but not consistently. So, I usually make sure my PHP scripts always return a reliable result. In the case of your script, the PHP function will return boolean true/false and the browser may interpret that as a numeric integer. Therefore, to make the result is more comprehensive, we just do a little more work on the server side and in the process get a more meaningful result at the client side:
    $rtn = 'success'; //Set default to return true
$serverPath = $_SERVER['DOCUMENT_ROOT'] . '/programs/';
if ( isset($_POST['endPath']) ) {
$endPath = $_POST['endPath'];
if ( !file_exists($serverPath.$endPath) ) {
if ( mkdir($serverPath.$endPath, 0777, true) ) { //may be true or false
//All okay so we do nothing here
} else {
$rtn = "error: file";
}
} else {
$rtn .= ": file already exits";
}
} else {
$rtn = "error: invalid post"; //Failure to provide valid $_POST forces return as false
}
exit( "$rtn" );

Now you will get either "success" or "error: [descriptive]"
This helps in debugging things as well.
 

Re: Asynchronous surprises

PostPosted: Sat Feb 08, 2020 9:21 am
by John Robin Dove
Many thanks for your helpful answer.