I need to run a node script inside my Laravel application.
I've tried using the Symfony Process, but it kill the process after the PHP execution and I need to keep the node process running, so my next step was try to use the shell_exec and exec functions. It's worked nice in the tinker and in Tinkerwell, but when I try to use inside the Laravel class it gives the following error 500:
production.ERROR: Call to undefined function shell_exec() {"exception":"[object] (Error(code: 0): Call to undefined function shell_exec() at ...
As it is a VPS I set my php.ini to disable_functions= but it still not working inside Laravel, only if I use it outside the framework.
Thanks in advance and sorry for my bad English.
Unfortunately this can't be done with exec() (nor system() or shell_exec()).
But if you install the pcntl extension, define something like:
<?php
function detached_exec($cmd) {
$pid = pcntl_fork();
if ($pid == 0) {
// Childe process main-loop goes here.
posix_setsid();
exec($cmd);
exit(0);
} else if ($pid == -1) {
// Process fork failed.
return FALSE;
}
return $pid;
}
And use like:
// Edit this:
$cmd = 'node --version';
$pid = detached_exec($cmd);
if($pid === FALSE) {
echo 'exec failed';
}
I ended giving up. I've developed an workaround.
Instead calling the node file by PHP, I made a node script whit express who receives a POST request and start the code.
Now I can put my node code in another server and it will keep running with no problems and make my system scalable.
Related
When I try to execute the command
php bin\console doctrine:generate:entity
I put the name of my bundle, the type of configuration that I want, in my case yml, but at the moment of insert the name of the first attribute for the entity the console starts to out the message
New field name (press <return> to stop adding fields): Aborted
Until I don't use the combination ctrl+c the console don't stop of print this message.
There is a question with the same problem here:
Doctrines automatically aborted in Symfony.
In that question someone says that is problem of stty and stdin but nobody explain how solve it.
Update:
In Symfony there are two functions that return a RuntimeException with the message Aborted. Both are in the QuesionHelper class. The first function is getHiddenResponse and the second is readFromInput. I suppose that the second function is returning the error but I don't know why, I have not yet been able to debug it but I think that the options are:
The condition of the if return false and the function fgets return false too. In this case can be that the variable $stream isn't equals to STDIN or that the function readline don't exists
The function readLine doesn't works.
This is the code of the readFromInput function:
private function readFromInput($stream)
{
if (STDIN === $stream && function_exists('readline')) {
$ret = readline();
} else {
$ret = fgets($stream, 4096);
}
if (false === $ret) {
throw new RuntimeException('Aborted');
}
return trim($ret);
}
I am trying to get the output of the command scheduled:summary function of laravel 5 and echo it in the browser, what i am currently doing is the following
public function scheduledCommands()
{
$output = new BufferedOutput;
Artisan::call('scheduled:summary',array(),$output);
return $output->fetch();
}
When i call this function i get this following error :
Use of undefined constant STDOUT - assumed 'STDOUT'
This method works for any other command just fine but this one, also when i execute it from CLI everything works fine and i get a table like this with my scheduled commands:
I don't understand what is different with this command, any further on why i get this error will be appreciated.
I just upgraded from 4.2 to 5.0. I got all of my commands working, but I noticed in one script I see an error (an expected error) which reports ErrorException. The problem is, it breaks my script from continuing instead of moving on the the next step in a foreach loop. The same error with the same script on 4.2 will report the error and continue.
4.2: Cannot connect to xyz.IP Error 60. Operation timed out
5.0: [ErrorException]
Cannot connect to xyz.IP Error 60. Operation timed out
For more context: I'm using the script to SSH into a couple of servers and run a Ping command. I'm using Phpseclib 1.0. I've tested phpseclib on my old 4.2 build and it works fine. 5.0 is where the problem started occuring.
Does anyone know how I can make the script continue to run after an ErrorException?
foreach ($query as $key => $value) {
$ssh = new Net_SSH2($value->origin_ip);
$key = new Crypt_RSA();
$key->loadKey(decryptIt($value->password));
if (!$ssh->login($value->username, $key)) {
exit('Login Failed');
}
$this->info(' Running Ping');
//$ssh->setTimeout(1);
if ($ssh->read('/.*#.*[$|#]/', NET_SSH2_READ_REGEX)) {
//echo "reading";
//$this->info(' Running Ping');
//$ssh->setTimeout(4);
$statusOutput=$ssh->exec("ping -c 1 -W 1 ".$value->destination_ip." >/dev/null 2>&1; echo $? ");
} else {
//echo "not reading";
$this->error("Unable to Read Ping");
}
}
To work with exceptions inline within a script, use a try...catch block:
try {
$value = someFunctionThatMayCauseAnException();
} catch (Exception $e) {
$errorMessage = $e->getMessage();
}
For more information, see the PHP manual entry for Exceptions
"Uncaught" exceptions will halt your script. Sometimes, that is the desired effect. For example, the SSH library you're using does not catch the exceptions that occur within the methods, they are allowed to bubble out to the calling script. Maybe your calling script catches them, or maybe you let them keep bubbling to your global exception handler. There are a number of ways to work with exceptions, but the general rule of thumb is that you don't catch them unless you're going to do something with it, like show an error message.
Your script would continue in the previous version because the error was, most likely, emitted as a warning or notice and returning false to indicate failure. With the newer PHP version, the library began emitting exceptions instead, at once indicating failure AND providing an exception object with details about the failure.
This means you'll have to restructure the logic within your loop instead of directly calling the function in a conditional if. You didn't specify which line is emitting the exception in your example, but for instance, this is one way that you could restructure to work with exceptions:
$errorMessage = false;
try {
$ssh->login($value->username, $key); // this code is attempted
} catch (Exception $e) {
// if an exception is emitted
// in the try block above, this block
// is reached. Otherwise, it is skipped
$errorMessage = $e->getMessage();
}
// $errorMessage can only be other than false from the exception catch block above
if ($errorMessage !== false) {
exit($errorMessage);
}
Solved it. I had a try catch which I modified.
Make sure the catch has a backwards slash like this:
try {
//code here
} catch (\Exception $e) {
print_r($e->getMessage());
}
I am running a php script in command line that connects to a oracle and mssql to fetch some data and write to a file. Actually it was a cron on linux machine which needed to be transfered to windows 2008.
The command is throwing the error:
fatal error call to undefined method MDB2_error::disconnect() in
path\to\script.php in line63
The code around line 63 are:
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
$db_clw->disconnect();
$db_banner->disconnect();
die($db->getMessage());
}
any idea?
You are calling the disconnect method on a MDB2 error object. That method does not have a disconnect method.
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
$db_clw->disconnect();
// ^ method does not exist
$db_banner->disconnect();
die($db->getMessage());
}
Since you call die immediately, there is probably no need to use disconnect at all, but if $db_clw is MDB2_Error, it has no method disconnect, so you should not attempt to call it. The attempt to call it will only occur if there is an error.
When it throws an error here
$db_clw->disconnect();
You already know that $db_clw is not a MDB2 Driver, but rather an error. As such, it doesn't have a disconnect method, so that line should be deleted.
You might want to surround your other disconnect statement there with a try-catch, such as:
$db_clw = MDB2::factory($config->database->CLW->dsn);
if (PEAR::isError($db_clw)) {
//We now know $db_clw is an error, don't attempt to disconnect.
try {
$db_banner->disconnect();
} catch (Exception e) {} //ignore it.
//die($db->getMessage()); Not sure if this is what you want, I'd think
die($db_clw->getMessage())
}
ignoring any problems with disconnecting, so that the statement die($db->getMessage()); is reached, which will help you determine why $db_clw = MDB2::factory($config->database->CLW->dsn); is failing.
Just noticed, and updated the code above to change the last statement to die($db_clw->getMessage());, which seems, probably, to be what your looking for there.
Asking for decent thoughts about this:
I'd like to implement some mechanism in PHP code that can run any external code and calls a callback function if one of the inclusions fails therein (include, require + *_once).
External code means that the code that is getting executed is not written by me nor is there control over it. It's included for testing. So having detailed info about inclusions failures deeper therein is helpful.
I'm runnning into the problem that it looks impossible to have a callback when a PHP fatal error happens.
What I tried so far:
Registering an error handler via set_error_handler - Does not work with fatal errors.
Created an object instance with a __destruct() method - Is not invoked with fatal errors.
Registered a shutdown function - Is not called on fatal errors.
In any of these I just wanted to fetch a debug_backtrace and then work with the information given.
So question shortly is: how to track failed file inclusions from within PHP code and call a function then.
I fear the answer to the question is no from my recent tries and searches, so anything insightful is highly appreciated. Even if your answer only strengthens the "not possible" point.
Additionally it's helpful as well if it's possible to find out which file is going to be included, so creating a debug output before the inclusion (failing or not) could be done at least.
Remarks:
Preferable w/o extensions. However if something exists, I'm eager to know as well.
External code means that the code that is getting executed is not written by me nor is there control over it. It's included for testing. So having detailed info about inclusions failures deeper therein is helpful.
Related:
How can I get PHP to produce a backtrace upon errors?
set_error_handler() doens't work for FATAL error (register_shutdown_function + error_get_last)
My suggestions are untested, here are some things to try:
If the required/included php files are classes autoload could be an option
function __autoload($class)
{
// try to load
}
If you can wrap the require/includes in a try catch block setting the error handler to use exceptions might also work: Update: doesn't work :(
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");
If the code you need to test can be tested in the command line using popen and xdebug you execute the program in a separate process if pclose returns -1 you could parse the backtrace from xdebug.
$cmd = 'php --php-ini path/php.ini file/to/run.php';
$output = '';
$popen = popen($cmd, 'rb');
while (!feof($popen)) {
$output .= fread($popen, 4096);
}
if (pclose($popen) < 0) {
// error - parse $output for xdebug backtrace
}
You don't need it. To load classes use __autoload function. To include static files use require_once. To load dinamic files you should check them before using (file_exeists, is_readable, etc) and throw exceptions if files not found to take backtrace.