0

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;
}
James
  • 679
  • 1
  • 8
  • 22
  • It can't connect to mysql. Make sure that mysql is running on your server. – aynber Sep 22 '17 at 18:58
  • @aynber I've been trying for 3 days, trust me, everything works fine (PHP, PDO, MYSQL). – James Sep 22 '17 at 18:59
  • So are you saying when you run it through web server it works, but not cli? If so, how do they differ? Is /usr/bin/php the PHP you think it is? – ficuscr Sep 22 '17 at 19:02
  • @ficuscr Exactly like that. It works fine if I use the PDO wrapper in my local host. It works well if I run it with bash ($ nohup…) but not when it's executed through PHP's func 'exec()'. And yes the main script includes /usr/bin/php. – James Sep 22 '17 at 19:06
  • Typical things... `localhost` vs `127.0.0.1`, SELinux, or something drastically different in the cgi's ini compared to cli's ini.... Ah osx... scratch selinux... connecting to '/tmp/mysql.sock '? – ficuscr Sep 22 '17 at 19:07
  • What command exactly are you passing through to `exec()`? – aynber Sep 22 '17 at 19:07
  • 1
    It might help if we can see your code (specifically your connection string) and that you tell us what you've already tried, since you state that you actually have searched and tried things. Then we won't need to repeat the same things here again. For example, have you checked this post? https://stackoverflow.com/questions/20723803/pdoexception-sqlstatehy000-2002-no-such-file-or-directory – M. Eriksson Sep 22 '17 at 19:09
  • @ficuscr Except It works fine if it's not run with PHP. So the PDO wrapper works just fine (I've tested it enough). – James Sep 22 '17 at 19:09
  • @aynber I updated the question with daemon's code example (including the command). – James Sep 22 '17 at 19:12
  • @Magnus Eriksson Yes I read that article a couple of hours ago. Although it didn't help me. – James Sep 22 '17 at 19:12
  • You need to show us the code that throws the error. Please also include what you've tried (like localhost vs 127.0.0.1, which seem to be a common reason for this error) – M. Eriksson Sep 22 '17 at 19:14
  • @Magnus Eriksson I explained that the PDO wrapper works fine in other instances other than the one ran by the php daemon launcher I made. Also that localhost vs IP thing has no issues, I had to do some reasearch when doing the PDOWrapper. The code line where it throws the error is at the top of the question in the link, but here it is: https://github.com/Adrian0350/SimplePDOWrapper/blob/master/src/SimplePDOWrapper.php#L107 – James Sep 22 '17 at 19:16
  • You are missing the point I feel. I'm not really concerned with this wrapper. The error is a mysql connection error no? My mantra with this stuff is , "what changed" / how do they differ? Sounds like PHP instance... cli – ficuscr Sep 22 '17 at 19:18
  • @ficuscr Yes, but you need to understand that everything works fine if it's not ran inside the PHP Daemon. Either Web or Bash works, but not with PHP's command `exec()`. :) – James Sep 22 '17 at 19:23
  • 1
    I get that. Things upstream effect everything downstream though. Environment apples and oranges... `exec('whoami');` Don't call it that way or let's focus on what does not work in the given context. Then we can step back and think about 'why'. – ficuscr Sep 22 '17 at 19:26
  • 3
    Try this: before you run your `exec` command, try `exec('which php');` and see if it gives the same as when you run it on the command line. I'm kind of curious if it's a permissions thing. – aynber Sep 22 '17 at 19:26
  • @aynber So when I do exec('which php > which.log') there's nothing inside the log. If I run it (with bash) it outputs '/opt/local/bin/php'. I think you're making a point there… – James Sep 22 '17 at 19:30
  • 1
    Try using the exact path for php in your exec command, then: `$daemon_command = '/opt/local/bin/php '.$this->script...` – aynber Sep 22 '17 at 19:34
  • @aynber Thanks a lot man! this worked just fine!. You might want to answer the question so I can give you the points you very well deserve :·3 – James Sep 22 '17 at 19:40

1 Answers1

1

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.

aynber
  • 22,380
  • 8
  • 50
  • 63