1

I've run into some trouble with a batch newsletter sending background script written in php.

I've noticed lots of differences between running a php via the browser, and via the php executable. I assume this is because php scripts executed directly by the executable don't have any interaction with apache. For instance, I have to set DOCUMENT_ROOT as an environment variable before calling the script or parse it as an argument, because $_SERVER["DOCUMENT_ROOT"] is not defined.

Now I've run into this problem when I try and connect to my database via PDO. Here's what happens:

C:/Users/hedge/Dev/PHPStorm/gpstudios/www/files/processes/send_newsletters.php hfBH6rCA 2>&1
    log.js:137 Warning: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: No such host is known.  in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php on line 42

Call Stack:
    0.0003     126144   1. {main}() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:0
    0.0016     155392   2. getConnection() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:14
    0.0023     196416   3. Connection->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\inc\config.php:20
    0.0023     196760   4. PDO->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php:42

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: No such host is known. ' in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php on line 42

PDOException: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: No such host is known.  in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php on line 42

Call Stack:
    0.0003     126144   1. {main}() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:0
    0.0016     155392   2. getConnection() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:14
    0.0023     196416   3. Connection->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\inc\config.php:20
    0.0023     196760   4. PDO->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php:42

PHP Warning:  PDO::__construct(): php_network_getaddresses: getaddrinfo failed: No such host is known.  in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php on line 42
PHP Stack trace:
PHP   1. {main}() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:0
PHP   2. getConnection() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php:14
PHP   3. Connection->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\inc\config.php:20
PHP   4. PDO->__construct() C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php:42
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: No such host is known. ' in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php:42
Stack trace:
#0 C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php(42): PDO->__construct('mysql:host=loca...', '<redacted>', '<redacted>')
#1 C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\inc\config.php(20): Connection->__construct('localhost', '<redacted>', '<redacted>', '<redacted>')
#2 C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php(14): getConnection()
#3 {main}
  thrown in C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\class\Connection.php on line 42

It seems localhost can't be resolved, but it doesn't explicitly report that in the logs.

How do I fix this?

If I replace 'localhost' in my PDO constructor with '127.0.0.1', it works. Clearly the issue is with resolving localhost. I am using proc_open() to start the script. I found that if I run the script through CMD prompt, it works. it looks like this: start /B php C:\Users\hedge\Dev\PHPStorm\gpstudios\www\files\processes\send_newsletters.php

The issue would appear to be with proc_open then...

EDIT

The problem is still unresolved but I've worked out the root of it:

proc_open($cmd, [['pipe', 'r'],['pipe', 'w'],['pipe', 'w']], $pipes, NULL, $environment_variables);

The problem is $environment_variables, an associative array which contains - you guessed it - environment variables. I came across this on php.net: http://php.net/manual/en/function.proc-open.php#117912

For those who are finding that using the $cwd and $env options cause proc_open to fail (windows). You will need to pass all other server environment variables;

However, even when I do just that, it still fails to resolve localhost.

EDIT 2

Problem resolved. The code provided by the helpful user on php.net used array($_SERVER), when in fact, you just need $_SERVER. So the code now looks like:

proc_open($cmd, [['pipe', 'r'],['pipe', 'w'],['pipe', 'w']], $pipes, NULL, array_merge($_SERVER, $environment_variables))

Huzzah! Thanks for the help everybody.

hedgehog90
  • 1,402
  • 19
  • 37
  • 1
    Please show your code. I suspect you're passing an incorrect hostname in `new PDO`. – Barmar Oct 06 '15 at 16:25
  • 1
    Do you have error reporting at `E_ALL`? I see you have warnings on but maybe not notices. Can you post the relevant pdo constructor in `Connection.php` so we can see how the DSN string is built? It actually looks to me like the string `localhost` is not being passed properly to the DSN, as I think I would expect the error message to have more information. – Michael Berkowski Oct 06 '15 at 16:25
  • @Barmar the contents of Connection.php are irrelvant. I'm simply doing `new PDO("mysql:host=$host;dbname=$db;charset=utf8", $username, $password);` You understand I'm running a command through the php executable and not via the browser? You will notice lots of differences, the inability to resolve localhost is clearly one of them. – hedgehog90 Oct 06 '15 at 16:35
  • Resolving hostnames should work the same in CLI and the webserver. What does `host localhost` say? – Barmar Oct 06 '15 at 16:37
  • is 'host' a Linux command? I should have mentioned in my original post I'm using Windows XAMPP. – hedgehog90 Oct 06 '15 at 16:39
  • @hedgehog90 But we're suggesting that the problem may be higher, in actually populating the variable `$host` whose _intended and expected value_ is `localhost`. Have you debugged that the value of that variable actually _is_ `localhost`? We need to rule out the possibility that a bad file include has caused those variables to be empty, for example. – Michael Berkowski Oct 06 '15 at 16:42
  • And have you simply substituted the hard-coded DSN `new PDO("mysql:host=localhost;dbname=your_database;charset=utf8", 'username', 'password');` – Michael Berkowski Oct 06 '15 at 16:46
  • I have reduced the script in question to 1 line: `$pdo = new PDO("mysql:host=localhost;dbname=gpstudios_main;charset=utf8", "username", "password");`... same error. Works fine when I load it as a webpage via the browser. – hedgehog90 Oct 06 '15 at 16:46
  • try to use 127.0.0.1 instead of localhost also try to open a command prompt and `ping localhost` and see what happens. – Alex Andrei Oct 06 '15 at 16:47
  • ping localhost works fine... if I replace localhost with 127.0.0.1 in the PDO constructor, it works fine. This is not a solution though. – hedgehog90 Oct 06 '15 at 16:49
  • Again, I'd like to make it clear that apache has no hand in this, and I'm pretty sure that's where the problem lies. I am simply running a command through the php function proc_open(), the command being: `start /B php send_newsletters.php hfBH6rCA 2>&1`. 'hfBH6rCA' is an argument to identify the newsletter I want to send – hedgehog90 Oct 06 '15 at 16:52
  • @hedgehog90 We understand Apache isn't involved, and since you did now substitute the hard-coded string, can you check from the CLI script something like `echo gethostbyname('localhost');` The expected output should be `127.0.0.1`. In the case of the PDO dsn, I believe the string `localhost` should be passed to the MySQL service for resolution, rather than resolved by PHP and passed as an IP to MySQL. – Michael Berkowski Oct 06 '15 at 16:59
  • Ok... echo gethostbyname('localhost') via proc_open returns 'localhost'. If I run the command via CMD prompt it returns 127.0.0.1. Updated my original question for clarity. – hedgehog90 Oct 06 '15 at 17:04
  • @hedgehog90 At this point, you should consider editing above to remove much of the original backtraces and description. Since you've narrowed it to `proc_open()` behavior, it would help if the question were titled something like 'proc_open() fails to resolve localhost on Windows' and focus on the stuff you've added to the end of the question. The fact that it was PDO failing is mostly irrelevant at this point. – Michael Berkowski Oct 06 '15 at 17:30

2 Answers2

1

Solutuion found here: http://php.net/manual/en/function.proc-open.php#117912

For those who are finding that using the $cwd and $env options cause proc_open to fail (windows). You will need to pass all other server environment variables;

The helpful user got it slightly wrong though, they put $_SERVER in an array. This is what worked for me:

proc_open($cmd, [['pipe', 'r'],['pipe', 'w'],['pipe', 'w']], $pipes, NULL, array_merge($_SERVER, $environment_variables))
hedgehog90
  • 1,402
  • 19
  • 37
0

IMHO, your host not found, please check host or see this

  1. PHP php_network_getaddresses: getaddrinfo failed: No such host is known
  2. mysql_connect: php_network_getaddresses: getaddrinfo failed: No such host is known using file values
Community
  • 1
  • 1
  • If you're just going to refer to other questions, you should flag this as a duplicate, not post an answer that just has links. – Barmar Oct 06 '15 at 16:36
  • Those questions are both about using real hostnames, not `localhost`. – Barmar Oct 06 '15 at 16:38