2016-06-30 11 views
0

Auf meinem Server (Ubuntu 14.04.4 LTS) habe ich einen Firefox installiert, sowie xvfb für den kopflosen Firefox-Betrieb und CasperJS mit SlimerJS. Ich habe auch ein CasperJS-Skript, das gut funktioniert. Ich möchte dieses Skript von PHP verwenden; Das ist die Essenz meines PHP-Skript für diese, machen sie es mytest.php nennen:Ein SlimerJS + kopfloses Firefox-Skript über PHP auf dem Webserver ausführen?

echo "php_sapi_name() " . php_sapi_name() . "\n"; // "cli" for php cli, "apache2handler" for php via webserver 

chdir(dirname(__FILE__)); 

$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; 

putenv("SLIMERJSLAUNCHER=/usr/bin/firefox46"); 
$cmdline = "xvfb-run $nodeModPath/casperjs/bin/casperjs --engine=slimerjs --debug=true mySlimerScript.js"; 

$returnString = shell_exec($cmdline); 
echo "$returnString\n"; 

EDIT: Beachten Sie, dass der Befehl auch nur sein könnte:

$cmdline = "xvfb-run $nodeModPath/casperjs/bin/casperjs --engine=slimerjs --debug=true 2>&1"; 

... das ist , ohne dass ein JS-Skript aufgeführt ist - in diesem Fall sollte die Hilfe ausgegeben werden (und im Fall von CLI-Zugriff - aber der gleiche Fehler wie unten beim Zugriff über den Webserver gemeldet wird)


Wenn ich diesen PHP-Skript von der Terminal-Befehlszeile (per SSH) ausführen, das ist durch PHP im CLI-Modus:

$ php mytest.php 

... alles gut läuft, gibt es überhaupt kein Problem.

Allerdings, wenn ich dieses PHP-Skript online über die Web-Server aufrufen, ist, dass über http://example.com/mytest.php, es nicht zuerst mit dem Fehler:

Gecko error: it seems /usr/bin/firefox46 is not compatible with SlimerJS. 
See Gecko version compatibility. If version is correct, launch slimerjs 
with --debug=true to see Firefox error message 

... und nach --debug=true Zugabe (wie bereits im Beispiel enthalten oben), habe ich diesen Fehler zusätzlich erhalten:

JavaScript error: resource://gre/modules/FileUtils.jsm, line 63: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIProperties.get] 

Also, anscheinend meine kopflos Firefox will nicht laufen, wenn PHP durch den Webserver aufgerufen wird (in diesem Fall, berichtet PHP, dass es die apache2handler SAPI verwendet).

Wüsste jemand, warum das passiert - und wie kann ich das Skript korrekt ausführen, wenn es von einem Webserver aufgerufen wird, genau so wie es im PHP CLI-Modus ausgeführt wird?

EDIT 2: Kann diesen Fehler nun auch über den CLI-Modus rekonstruieren und kann bestätigen, dass dies auf den Benutzer zurückzuführen ist; so ohne JS Skript im $command zur Verfügung gestellt, bekomme ich diese:

$ sudo -H -u root php mytest.php 
... 
Usage: casperjs [options] script.[js|coffee] [script argument [script argument ...]] 
     casperjs [options] test [test path [test path ...]] 
     casperjs [options] selftest 
... 

$ sudo -H -u www-data php mytest.php 
JavaScript error: resource://gre/modules/FileUtils.jsm, line 63: NS_ERROR_FAILURE: Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIProperties.get] 
Gecko error: it seems /usr/bin/firefox46 is not compatible with SlimerJS. 
See Gecko version compatibility. If version is correct, launch slimerjs 
with --debug=true to see Firefox error message 
+1

Erste Gedanken: Dateien Berechtigungen wie das Ausführen des Skripts im 'CLI' Modus wird der Benutzer es ausführen, aber über den Webserver wird der Benutzer 'www-Daten'. Möglich, nicht wahr? –

+0

In der Tat, @ php-dev, aber ich kann nicht wirklich herausfinden, wessen Berechtigungen das Problem sein würde; hier rufe ich 'xvfb-run' an, das' casperjs' aufruft, das 'slimerjs' aufruft, das kopflosen Firefox aufruft. Gibt es eine Möglichkeit, irgendwo in diesem Fall nach Berechtigungsfehlern zu suchen? Ich habe versucht '/ var/log/apache2/error-mysite.log', aber es meldet nur PHP-Sachen wie' Versuch, Eigenschaft von Nicht-Objekt zu bekommen', wenn der 'shell_exec'-Aufruf fehlschlägt. – sdbbs

+1

Versuchen Sie, 'stderr' Ausgabe in' stdout' oder eine Datei umzuleiten. –

Antwort

4

Nun, das war ein unangenehmes Problem. Ich landete einen strace tun, und den Vergleich der Protokolle, für die root Benutzer und dem www-data Benutzer, wenn eine vollständige slimerjs läuft (die vollständige Befehlszeile kann durch Zugabe von echo es zu /path/to/slimerjs-0.10.1-pre/slimerjs zu finden):

sudo -H -u www-data strace \ 
    /usr/bin/firefox46 -app /path/to/slimerjs-0.10.1-pre/application.ini \ 
    --profile /path/to/firefox-46.0.1/profile-46 -no-remote --debug=true /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/bootstrap.js --casper-path=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs \ 
    --cli 2>&1 \ 
    | tee /tmp/strace.log 

sudo -H -u root strace \ 
    /usr/bin/firefox46 -app /path/to/slimerjs-0.10.1-pre/application.ini \ 
    --profile /path/to/firefox-46.0.1/profile-46 -no-remote --debug=true /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs/bin/bootstrap.js --casper-path=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/casperjs \ 
    --cli 2>&1 \ 
    | tee /tmp/straceR.log 

Wenn diese Protokolle werden im Vergleich jetzt in etwa meld, dann wird der Start schließlich an einem Punkt, wie diese divergierenden:

mkdir("/root/.innophi", 0700)   = 0 
mkdir("/root/.innophi/slimerjs", 0700) = 0 

... [vs.] ... 

mkdir("/var/www/.innophi", 0700)  = -1 EACCES (Permission denied) 
access("/var/www/.innophi", F_OK)  = -1 ENOENT (No such file or directory) 

So casperJS im Grunde versucht, ein Verzeichnis im Home-Verzeichnis des Benutzers zu erstellen; Das Problem ist, www-data 's $HOME ist /var/www, wo es scheinbar keinen Schreibzugriff hat!

So ist die einfachste Sache für mich war, zu „hacken“, um die $HOME Umgebungsvariable in dem mytest.php Skript, und setzen Sie sich auf /tmp, wo www-data definitiv Schreibrechte:

... 
putenv("SLIMERJSLAUNCHER=/usr/bin/firefox46"); 
putenv("HOME=/tmp"); 
... 

... und whaddayaknow schließlich arbeitet das Skript unter dem www-data Benutzer von CLI zu:

$ sudo -H -u www-data php test_commands.php 
... 
Options: 

--verbose Prints log messages to the console 
--log-level Sets logging level 
--help  Prints this help 
... 

Btw, das .innophi Verzeichnis scheint auch in erwähnt werden https://docs.slimerjs.org/current/configuration.html#profiles,