SQLSTATE[HY000] [2002] No such file or directory - PHP Daemon - php

I made a PHP daemon launcher (I execute an independent [which is an argument passed to the daemon] script through exec()) and the script that this PHP daemon runs uses a PDO wrapper that I made as well.
The thing is, when I run the script through the PHP daemon ($ php), my PDO wrapper can't connect and throws SQLSTATE[HY000] [2002] No such file or directory.
The daemon_script.php includes #!/usr/bin/php before the <?php opening tag.
Now, I've been searching here since yesterday and found a couple of approaches but none is my specific case and can't manage to make it work, so I thought you'd have an idea on what I'm doing wrong.
Thanks in advance.
Using:
PHP 7.0.21 (although intended to implement it with PHP 5)
MYSQL Ver 14.14 Distrib 5.6.34, for osx10.12 (x86_64)
Daemon's start() method:
/**
* Starts the script.
* Also receives a script and sets it, then it runs it.
*
* #param string $script Optional script to start.
* #throws Exception Could not init.
* #throws Exception Could not save pid.
* #return boolean
*/
public function start($script = '')
{
if ($script)
{
$this->setScript($script);
}
$initialized = false;
$daemon_command = 'php '.$this->script.' > script.log 2>&1 & echo $! &';
try
{
$daemon_pid = exec($daemon_command, $output);
if (!$daemon_pid)
{
throw new Exception('Could not initialize. Invalid script: '.$this->script);
}
if (!file_put_contents($this->pid, $daemon_pid))
{
exec('kill '.$daemon_pid);
throw new Exception('Could not save process id "'.$daemon_pid.'"… killing it.');
}
usleep(50000);
if (!($initialized = $this->checkPID($daemon_pid)))
{
file_put_contents($this->pid, null);
throw new Exception('Script died unexpectedly!');
}
}
catch (Exception $e)
{
$this->errors = array(
'code' => $e->getCode(),
'message' => $e->getMessage()
) + $this->_errors;
}
return $initialized;
}

You need to set the full path to PHP in your command in order for exec() to properly find it. Since php is located in /opt/local/bin/php, just add it like this:
$daemon_command = '/opt/local/bin/php '.$this->script.' > script.log 2>&1 & echo $! &';
As a note, cron often works the same way, because it doesn't access the same PATH variables that a command-line user does.

Related

Laravel Flysystem SFTP: How to check if connection is successful or not

I'm using Flysystem SFTP in Laravel 8. I've multiple accounts for sftp and I'm looping on every one for making adapter and then reading files from server. This all is working through console command and is registered in Schedule. The issue is when any of the connection fails due to username or password issue, it stops the execution of schedule task and skips the remaining. How can I check if connection is successful or not and continue to my next sftp connection. Thanks in advance.
foreach ($credentials as $cred) {
try {
$driver = Storage::createSFtpDriver($cred);
if($driver->exists('/reports/')) {
//Other code
} else {
continue;
}
} catch (Exception $e) {
continue;
}
}
See SFTP V3, there SftpConnectionProvider reads:
connectivity checker (must be an implementation of League\Flysystem\PhpseclibV2\ConnectivityChecker to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
So the answer is SftpConnectivityChecker implements ConnectivityChecker
... to be passed into SftpConnectionProvider constructor. That interface only has one single method to override:
public class SftpConnectivityChecker implements ConnectivityChecker {
public function isConnected(SFTP $connection): bool {
$connected = false
// TODO: inspect the $connection status.
return $connected;
}
}
Likely to be configured alike this:
'sftp' => [
'connectivityChecker' => 'SftpConnectivityChecker'
]
And don't use continue, but handle the exception instead of ignoring it.
I don't know if it is good way or not but in my case, it is working fine. I just solved it by applying \ with Exception class and it is going fine.
foreach($credentials as $cred){
try {
$driver = Storage::createSFtpDriver($cred);
if($driver->exists('/report/')){
echo "Found for ".$cred["username"];
}
else{
continue;
}
}
catch (\Exception $e) {
continue;
}
}

PHP: How to kinda CATCH exec() WARNINGs & continue execution of main program

I am currently using this command to validate some PHP files.
$op=null; $ret=null; exec("php -l '$file' 2>&1",$op,$ret);
Unfortunately on the customer's shared hosting (linux) it fails with the line below obviously because some commands are disabled:
Warning: exec(): Unable to fork [php -l '/path_to_the_file.php' 2>&1] in /my_program.php on line 559
I want to avoid this Warning at all costs because as soon as I disable debugging, the host shows its 500 error page which completely kills the webpage (for some strange reason).
Try/Catch does not work at all.
try {
$op=null; $ret=null; exec("php -l '$file' 2>&1",$op,$ret);
if($ret != 0) {
throw new Exception("'$file' failed syntax check");
}
} catch(Exception $e) {
$this->addLog(LOG_ERR, 'syntax error', $e);
continue;
}
Any ideas how to avoid this Warning?
This is the only solution that worked for me.
I used a couple of functions to check if exec is available and enabled:
private function commandEnabled($comm) {
return is_callable($comm) && !($this->commandDisabled($comm));
}
private function commandDisabled($comm) {
return !(false === stripos(','.ini_get('disable_functions').',', ','.$comm.','));
}
if (!$this->commandEnabled('exec')) {
// I run my code here
}
UPDATE:
I just found out from this post https://stackoverflow.com/a/29268475/1806085
that you can also catch the error in PHP 7+ with this:
try {
some_undefined_function_or_method();
} catch (\Error $ex) { // Error is the base class for all internal PHP error exceptions.
var_dump($ex);
}

How to get events in PAMI

I successfully insttalled PAMI in my server where asterisk is setup. And i wrote a new php file which
class A implements IEventListener
{
public function handle(EventMessage $event)
{
print_r("Inside");
}
}
$pamiClient = new PamiClient($pamiClientOptions);
$pamiClient->registerEventListener(new A());
$pamiClient->open();
$running = true;
while($running) {
$pamiClient->process();
usleep(1000);
}
$pamiClient->close();
But when i generate a call it doesnot catch the event. How can i know it is connected with asterisk, and how can i test this? Iam justng running this php file .
How i can know it connected to asterisk:
tcpdump -vv dst port 5038
how can i test this
Use debugger.

After php upgrade pcntl_fork causing "errno=32 Broken pipe"

I recently upgraded from php 5.4.26 to 5.4.28 after the upgrade I am getting this error
Notice: Unknown: send of 6 bytes failed with errno=32 Broken pipe in Unknown on line 0
When ever I run the following code:
<?php
$tasks = array(
'1' => array(),
'2' => array(),
);
ini_set('display_errors', true);
class RedisClass {
private $redis;
public function __construct()
{
$this->redis = new Redis();
$this->redis->connect('localhost', 6379);
}
}
$redis = new RedisClass();
foreach ($tasks as $index => $task)
{
$pid = pcntl_fork();
// This is a child
if($pid == 0)
{
echo "Running ".$index." child in ". getmypid() ."\n";
break;
}
}
switch($pid)
{
case -1 :
die('could not fork');
break;
case 0:
// do the child code
break;
default:
while (pcntl_waitpid(0, $status) != -1)
{
$status = pcntl_wexitstatus($status);
echo "Child completed with status $status\n";
}
echo "Child Done (says: ". getmypid() .")";
exit;
}
If I only fork one child then I do not get the PHP Notice. If I run any more than 1 child I get the PHP Notice for every child except the first child.
Does anyone have any clues as to what is going on here?
I am assuming it is trying to close the Redis connection multiple times but this is code I have been running for at least 4 months with out any issues.
It only starting displaying these notices after the upgrade to 5.4.28.
I have looked at the PHP change logs but I cannot see anything that I think may explain this issue.
Should I report this to PHP as a bug?
UPDATE:
Looks like it "may" be a Redis issue, I am using phpredis I tested the same code with a mysql connection instead of loading Redis and I do not get the error.
class MysqlClass {
private $mysqli;
public function __construct()
{
$this->mysqli = mysqli_init(); //This is not the droid you are looking for
$this->mysqli->real_connect('IP_ADDRESS',
'USER_NAME',
'PASSWORD');
}
}
$mysql = new MysqlClass();
The problem here is that you do not reconnect Redis in the child process. Like Michael had said, you do not have an active connection from the second child onwards. That mysql example should not work if you also make some queries.
I have had the exact problematic behaviour with the "MySQL server has gone away" error and also with Redis.
The solution is to create a new connection to MySQL and to Redis in the child. Make sure if you have a singletone that handles the MySQL/Redis connection to reset the instances ( that was also a problem for me ).

Catch an exception in a shutdown function

I'm working on some PHP code that needs to obtain a database resource, mark it as locked for the duration of its run and mark it as not locked when done. The lock is obtained at startup by updating a value in the table, and I've registered a shutdown function to release the lock when the script terminates for any reason.
The problem I'm having is that the connection to the server (a Microsoft SQL database server) doesn't appear to be very reliable in the live environment, and that seems to be the usual reason for abnormal script termination. Obviously I can't unlock the database resource when I'm not connected but I at least want to be able to handle the failure to do that cleanly.
The following is a heavily cut down version of the main script.
try {
echo "Connecting to server...\n";
$obj_adaptor = get_remote_db ();
echo "Beginning sync...\n";
if (FALSE != ($bol_locked = $obj_adaptor -> lock_server_db ())) {
// Do work here
} else {
throw new RuntimeException ("Failed to obtain remote database lock!");
}
} catch (Exception $obj_ex) {
echo "Operation failed with an exception!\n\n";
echo "Details: \n";
echo $obj_ex -> getMessage () . PHP_EOL;
echo $obj_ex -> getTraceAsString () . PHP_EOL;
}
My shutdown function looks like this:
$arr_shutdown_func = function () {
global $bol_locked, $obj_adaptor;
if ($bol_locked) {
echo "Releasing lock...\n";
try {
echo $obj_adaptor -> unlock_server_db ()?
"Done\n":
"Failed to unlock database! Use force_remote_db_unlock script to force a database unlock\n";
} catch (PDOException $obj_ex) {
echo "Failed to unlock database! Use force_remote_db_unlock script to force a database unlock\n";
}
} else {
echo "No lock to release\n";
}
};
// Set up ctrl-c listener
if (function_exists ('pcntl_signal')) {
pcntl_signal (SIGINT, $arr_shutdown_func);
pcntl_signal (SIGTERM, $arr_shutdown_func);
// Register shutdown functions
register_shutdown_function ($arr_shutdown_func);
set_exception_handler ($arr_shutdown_func);
I was expecting in the event of the connection being lost for the script to attempt to release the database lock but failing, and echoing out the message about not being able to release the lock.
However, what I actually get is:
PHP Fatal error: Uncaught exception 'Zend_Db_Statement_Exception'
with message 'SQLSTATE[HY000]: General error: 20047 DBPROCESS is dead
or not enabled [20047] (severity 1) [(null)]' in
Zend/Db/Statement/Pdo.php:238
I've tried to find a definitive answer on whether or not it's possible to catch exceptions in a shutdown function but haven't had much luck so far so I'm still looking. However, if it's possible to deal with exceptions in a shutdown function I'd appreciate knowing what's wrong with the approach I'm applying.
I've just tested this out with a simple code and I don't get disconnected before shutdown function.
<?
mysql_connect('localhost','xxx','xxx') or die(mysql_error());
mysql_select_db('xxx');
register_shutdown_function("s");
function s() {
echo 'xxxx';
$qa = mysql_query('SELECT * FROM xxx') or die(mysql_error());
while($q = mysql_fetch_array($qa)) {
print_r($q);
}
}
?>
What version of PHP are you using?
PHP 5.5.3 (cli) (built: Aug 23 2013 08:41:45) Copyright (c) 1997-2013
The PHP Group Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend
Technologies

Categories