Run NodeJS commands from PHP - php

I have the following PHP code that is run when a user clicks a button on a local intranet page to run some Node JS commands. e.g.
exec('npm install', $output);
$output = implode(PHP_EOL, $output);
echo $output;
But the command doesn't seem to get run... It does if I type the command into the command prompt and run it...
I don't see any errors and NodeJS is set as a system variable in the Path so it should know what grunt is... Any ideas? Other commands, e.g. whoami run fine.
Any ideas?
I'm on Windows 7.
Update: Based on the comments below I can now get an error with:
exec('npm install 2>&1', $output, $returnCode);
$output = implode(PHP_EOL, $output);
echo $output . ' ' . $returnCode;
And this is the error:
TypeError: Cannot call method 'get' of undefined at C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:310:23 at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:80:7 at Array.forEach (native) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:79:13 at f (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\once\once.js:16:25) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:108:14 at Conf. (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\npmconf.js:179:14) at Conf.next (C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\npmconf\lib\load-prefix.js:48:20) at C:\Program Files (x86)\nodejs\node_modules\npm\node_modules\mkdirp\index.js:37:53 at Object.oncomplete (fs.js:107:15) C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:33 throw new Error('npm.load() required') ^ Error: npm.load() required at Object.npm.config.get (C:\Program Files (x86)\nodejs\node_modules\npm\lib\npm.js:33:11) at exit (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\error-handler.js:49:27) at process.errorHandler (C:\Program Files (x86)\nodejs\node_modules\npm\lib\utils\error-handler.js:316:3) at process.emit (events.js:95:17) at process._fatalException (node.js:272:26) 7
So it looks like the PHP knows where NodeJS and NPM is... but can't run it?
If I do whoami in the PHP I get: nt authority\iusr
But if I do it from the command prompt then I get: dom\cameron
I wonder if it's because PHP runs it as a different user to when I run it directly in the command prompt...

Okay I've managed to fix this!
Basically you need to run the website (where the PHP file lives) as the same user as where NodeJS is run from!
To achieve this I did the following in IIS:
1.) Find the website
2.) Choose basic settings
3.) Click the connect as... button
4.) Choose 'specific user'
5.) Enter `dom/cameron` and my password
6.) Restart IIS
If anyone has any ideas for how to get NodeJS running for the default nt authority\iusr then feel free to post an answer :)

You defined npm in WINDOWS path, but did PHP recognize it?
I suggest you should test it with writing the full NPM path in the exec. If it works, than you should call putenv() with correct parameters before executing npm install..
So first try:
exec('C:\npm-test\npm install', $output);
$output = implode(PHP_EOL, $output);
echo $output;
And if it works, use the putenv() command before calling exec(). Example:
putenv("npm='C:\npm-test\npm'");
//and then exec(...)

The error you're getting indicating that an object is not defined. It's quite possible that a module is simply not loading because you're not running the script from the correct location, and relative links to some include are not working. Running as the correct user might fix it. Or try changing to the correct directory before running the node script. Or change the location of the links inside the node script.

Related

CentOS Linux console command versus PHP exec(command)

I have a C program that I wrote called convert3to5, originally written for CentOS / Fedora 32bit system in early 2010. I am moving it to new CentOS 6.x 64bit system host.
From a CentOS Putty console I can run the convert3to5 command just fine; here is a sample of it running from my console:
[root#cloud convert3to5]# ls
CircleStar convert3to5 Convert3To5.txt test.tif
[root#cloud convert3to5]# ./convert3to5 /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif
TIFFReadDirectory: Warning, /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif: wrong data type 7 for "RichTIFFIPTC"; tag ignored. Image has an undefined fillorder - using default: MSB2LSB
The above is a normal completion of convert3to5 and I get a SV-DIS160217B.bmp that is placed in /var/www/webadmin/data/www/mydomain.com/uploads/ So running it from console works fine.
Question - I am attempting to run the same exact command from PHP using the exec(command, output, return) command as follows:
chdir($sv_path.$c3to5_path); //change our working directory to "/convert3to5" directory
$command = "./convert3to5 $targetFile 2>&1";
$result = exec($command, $output, $return);
// the output of the above command - is a .bmp file it will be placed in the same path as the input .tif file
I get the following $result:
ERROR: Unable to convert
/var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif to 5
color BMP file: Open file Error: Tiff_3_to_BMP_5_.lut!
My convert3to5 does need to open Tiff_3_to_BMP_5_.lut
Why does it find Tiff_3_to_BMP_5_.lut when I run convert3to5 from a console prompt but not from PHP exec(...) in both cases my pwd shows that I am in
[root#cloud convert3to5]# pwd
/var/www/webadmin/data/www/mydomain.com/myView/convert3to5
I have also verified pwd is correct from my PHP script after the
chdir($sv_path.$c3to5_path);
Tiff_3_to_BMP_5_.lut is in CircleStar directory - the path to CircleStar is /var/www/webadmin/data/www/mydomain.com/myView/convert3to5/CircleStar
Summary: ./convert3to5 works while PHP exec('convert3to5 ..) does not appear to work.
Can anyone suggest the difference and how to fix and/or debug?
Thanks
You're running the console from the convert3to5 directory, and I suspect your old C program used a relative path to the .lut file, possible relative to the .tif?
What if in the console example you did
cd ../..
./path/to/convert3to5/convert3to5 /var/www/webadmin/data/www/mydomain.com/uploads/SV-DIS160217B.tif
Might be related to $targetFile. Print that and see if it's the full path.
Finally, run
/full/path/to/convert3to5 fullTargetPath
If that works, then as a workaround, if you just do exec('/full/path/to/convert3to5 $fullTargetPath, ..) it should behave like the console.
Per my above comment to wonton:
From the console I was running as root (so fully privileged). I supposed my PHP script will run as the "apache" user on the server?
Here was the problem I believe: I looked at the CircleStar directory privileges where the Tiff_3_to_BMP_5_.lut file exists. CircleStar had rw-r--r-- (0644) when running as root from console this allowed my convert3to5 program to find and open Tiff_3_to_BMP_5_.lut file just fine. However not the PHP exec(...) once I changed the privilege on CircleStar to rwxr-xr-x (0755) PHP exec(...) ran fine!
So ultimately it was a permission issue.

Not able to run wkhtmltopdf commad through shell_exec() function in php but same command works on command line

I'm in trouble and that much confused about a php shell_exec command.
When the command is execute by PHP I have no error but the execution fails. If I use exactly the same command from a terminal it works.
Here's the command :
/usr/bin/wkhtmltopdf --lowquality --dpi 300 --encoding utf-8 "/tmp/knplabs_snappyxa9otq.html" "/tmp/knplabs_snappyv3pD7h.pdf"
When I lauch this from a terminal :
$ /usr/bin/wkhtmltopdf --lowquality --dpi 300 --encoding utf-8 "/tmp/knplabs_snappyWG9XTd.html" "/tmp/knplabs_snappyv3pD7h.pdf"
Loading page (1/2)
Printing pages (2/2)
Done
But from my php script :
// Construct the previous command
$command = $this->buildCommand($url, $path);
../..
shell_exec($command);
../..
$content = file_get_contents($path);
../..
I've test the output of shell_exec, it's empty.
The log :
Warning: file_get_contents(/tmp/knplabs_snappyv3pD7h.pdf): failed to open stream: No such file or directory in /*****/lib/snappy/SnappyMedia.class.php on line 64
No permission pb in the /tmp directory :
$ ls -la /tmp
total 448
drwxrwxrwt 16 root root 4096 mars 12 21:51 .
../..
I've tried avec the PHP exec() function to get error informations, I just get an "1" error code in return_var and nothing in output.
For information this issue appear on my test server, my desktop computer but not on my notebook. All the 3 are with sames PHP, Apache, Mysql versions.
I don't understand anything ...
Thanks for any help, I'm loosing my mind.
David.
I've found the solution here : Executing wkhtmltopdf from PHP fails
Thanks to Krzychu.
First to get information from the shell_exec command add " 2>&1" at the end of the command. In that way you will get information in return of the command :
$no_output = shell_exec($command);
echo $no_output; // nothing
$output = shell_exec($command . ' 2>&1');
echo $output; // in my case : "cannot connect to X server"
The solution :
Not use the wkhtmltopdf ubuntu package (0.9.9-4)
Use the official package from the Wkhtmltopdf download page
So no need to install xvfb ! (I've seen this advice many times)
Looks like a user's permissions issue.
When you run the command from the terminal, it is the user account, currently used, which does have the right permissions, to run a command in /usr/bin, and execute the specific file.
When you run it from the php script, it is the http server account on your system, which needs the permission to execute the file in /usr/bin. Usually this is the apache user.
How you should setup permissions depends on your system. Just remember that what is allowed for apache, is allowed for anyone accessing your http server.
I have had this problem for ages and adding . ' 2>&1' after the $command has somehow solved the problem.
this:
$output = shell_exec($command . ' 2>&1');
instead of:
$output = shell_exec($command);
No idea why but it works and I'm grateful.
Is it a shared hosting? It seems like shell_exec is a restricted function. Try running error_reporting(E_ALL); ini_set('display_errors', 1); before calling shell_exec.
I stumbled upon the same Problem, in my case an absolut Path in the exec Command like /var/www did not work, I had to use relative Paths from the point where I executed the php File.
I also wanted to notice, that it did not work using shell_exec, however it worked using normal exec command, not sure wheres the difference here.

php libreoffice shell_exec not working

I am trying to convert .docx file to .html using php shell_exec in CentOS 6.5
My php code:
$command = "libreoffice --headless -convert-to html resume.docx 2>&1";
$result = shell_exec($command);
echo $result;
When I run the index.php at http://localhost/converter/ it gives me:
javaldx: Could not find a Java Runtime Environment! Warning: failed to read path from javaldx /usr/lib64/libreoffice/program/soffice.bin X11 error: Can't open display: Set DISPLAY environment variable, use -display option or check permissions of your X-Server (See "man X" resp. "man xhost" for details)`
while in terminal it is working perfectly:
cd /var/www/html/converter/
libreoffice --healdess -convert-to html resume.docx
here it creates resume.html in my /var/www/html/converter/.
Hi i have the same problem, i want to convert PDF's from DOCS created with PHP, i'm using OpenSuse 12.3 with LibreOffice, tried many things, finally i detect that the error is in folder:
1.- First check that you don't have disabled shell_exec in php.ini, and open_basedir don't restrict your access folders.
2.- Run the command as a simple user in shell (terminal)
export HOME=/tmp && soffice --headless --convert-to pdf --outdir /srv/www/htdocs/ /srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx
3.- If it works, you only have to put the correct folders in your code, when i run this code in PHP, it show me a blank page, so i check the access_log of apache for any hint:
[Java framework] Error in function createSettingsDocument (elements.cxx).
javaldx failed!
Warning: failed to read path from javaldx
terminate called after throwing an instance of 'com::sun::star::uno::RuntimeException'
Note: my error was in using export HOME=/tmp, i checked that the folder in root system has 777 for tmp, but the problem was that apache don't acces to it, maybe search for a relative folder of the script, but after test many things i only put a folder with permissons for wwwrun HOME=/srv/www/htdocs/folder_with_777
This is my final code, that works..
<?php
function word2pdf()
{
echo "Procesando";
$result = shell_exec('export HOME=/srv/www/htdocs/Creecimientos/sic/ && soffice --headless --convert-to pdf --outdir /srv/www/htdocs/Creecimientos/sic/ /srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx');
echo $result;
}
word2pdf();
?>
In fact, it prints: convert srv/www/htdocs/Creecimientos/sic/app/webroot/usuarios/2/8_Pagare_CreePersonas.docx -> /srv/www/htdocs/Creecimientos/sic//8_Pagare_CreePersonas.pdf using writer_pdf_Export, after succes.
I made other changes before in desesperate mode, but none of them solved the problem, tried to change owner to soffice wich found it witch $ ls -l $(which libreoffice), tried with 777, etc..
/* This command will work on centos 6 /7 with installation of libreoffice headless package */
First install package on centos as :
yum install libreoffice-headless
/* following code work to extract text format from */
<?php
$result = exec("export HOME=/tmp/ && /usr/bin/libreoffice --headless --convert-to txt:Text --outdir /tmp filePath");
var_dump($result);
?>
Most likely the user that LibreOffice is ran as, does not have a writeable home directory so LibreOffice fails to create it's config directory and then it cannot create it's config files and then fails to load Java, because it cannot write the default config. A bit silly I know.
Try adding this parameter: -env:UserInstallation=file:///tmp/whateverhere
I don't have enough reputation to comment on TD_Nijboer's answer, but the answer to his specific problem appears to be that soffice needs to be able to read & write config information somewhere. The first place it tries to do this is the libreoffice directory in ~/.config ('~' means "the current user's home directory").
In Debian, by default, the www-data user has the home directory /var/www, and does not have write permission there.
If you make sure it has permission to either create ~/.config itself, or libreoffice within an existing ~/.config, I expect it will work.
2 things, 1st the command is soffice --headless,
2nd i have an similar javaldx error and it has to do with permission.
when executing as root it works fine, but php executes as www-data.
if anybody knows a good way to execute libreoffice from php please let me know.
as i'm getting an error code 77 saying:
[Java framework] Error in function createSettingsDocument (elements.cxx).
javaldx failed!
Warning: failed to read path from javaldx

gpg encryption failed: file open error

I have been going nuts with this..
I have gnupg installed on my CentOS server and I try to encrypt uploaded files (uploaded via a PHP page). On the server via the command line, it works perfectly. But via the php script, it fails with this error:
gpg: /path-to-my-file/my-file: encryption failed: file open error
The user apache (which I think is used to run the exec command) has read/write in the directory of the file.
The file is uploaded fine (I can see it afterward as I removed the deletion of the unencrypted file from my code) and can be deleted correctly via the php site.
the command I run is the following
/path-to-gpg/gpg --homedir=/path-to-my-home-gnupg/.gnupg -e -r therecipient#email the-unencrypted-file
Any idea how I could tackle this?
thanks
A few things to check:
Run system("ls " . escapeshellarg($file)) and check the result — is it file not found? Permission denied? That will help you debug.
Run system("whoami") to make sure PHP is running as who you think it is.
Run echo "<pre>ls " . escapeshellarg($file) . "</pre>" then copy+paste the command and run it from the shell to make sure that the path to the file is what you expected it to be.
Also, I believe CentOS runs SELinux by default… If you've got it installed, check the logs (in /var/log/) to see if SELinux is preventing Apache from executing GPG.
Try running the command with actual apache user privileges in verbose mode:
su apache -c /path-to-gpg/gpg -vv ...

What is the difference between running a script from the command line and from exec() with PHP?

I'm trying to run a Python script using exec() from within PHP. My command works fine when I run it directly using a cmd window, but it produces an error when I run it from exec() in PHP.
My Python script uses NTLK to find proper nouns. Example command:
"C:\Python25\python.exe" "C:\wamp\projects\python\trunk\tests\find_proper_nouns.py" "I went to London this morning"
returns [London] when I run it from cmd, but throws an error in the Apache log when I run the same command from exec().The script is defintely getting run OK - if I change the python script to be print "Hello World" that is returned fine.
I know it's a big ask for anyone to know how to fix this NLTK error, but I could really do with any pointers as to why running it from exec is different to cmd. (The command is identical).
I'm running WAMP on Windows 7 with Apache 2.2.11.
Here's the error in the Apache log:
Traceback (most recent call last):
File "C:\wamp\projects\python\trunk\tests\find_proper_nouns_command_line.py", line 6, in <module>
parts = nltk.pos_tag(text)
File "C:\Python25\lib\site-packages\nltk\tag\__init__.py", line 62, in pos_tag
tagger = nltk.data.load(_POS_TAGGER)
File "C:\Python25\lib\site-packages\nltk\data.py", line 590, in load
resource_val = pickle.load(_open(resource_url))
File "C:\Python25\lib\site-packages\nltk\data.py", line 669, in _open
return find(path).open()
File "C:\Python25\lib\site-packages\nltk\data.py", line 451, in find
raise LookupError(resource_not_found)
LookupError:
**********************************************************************
Resource 'taggers/maxent_treebank_pos_tagger/english.pickle' not
found. Please use the NLTK Downloader to obtain the resource:
>>> nltk.download().
Searched in:
- 'C:\\nltk_data'
- 'D:\\nltk_data'
- 'E:\\nltk_data'
- 'C:\\Python25\\nltk_data'
- 'C:\\Python25\\lib\\nltk_data'
- 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Roaming\\nltk_data'
**********************************************************************
You have to run nltk.download() and choose 'maxent_treebank_pos_tagger'. You must make a python script and in it put:
#!/usr/bin/python
import nltk
nltk.download('maxent_treebank_pos_tagger');
then run it from command line. It will install the data files for the POS tagges, which you don't have installed yet.
After you do this it should work.
Your web server likely runs with other privileges than yourself. Possible problems include:
Path/file permission: can the web server user access the files it needs?
Different environment: are all necessary environment variables (PATH, Python-specific stuff, …) set?
Configuration: are there per-user configurations for Python or the module?
Tip: execute set in both the command prompt and from the PHP process and check the differences.
From the shell/terminal, you can use:
sudo python -m nltk.downloader maxent_treebank_pos_tagger
It will install maxent_treebank_pos_tagger (i.e. the standard treebank POS tagger in NLTK).

Categories