Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS with PHP

Tags:

php

node.js

I am a PHP developer who just started learning Node.js and I saw this video: https://www.youtube.com/watch?v=_D2w0voFlEk where it is explained that a html file can be given as response to the browser which is fine.

Now, my question:

If I am running Node.js and PHP in the same server and if the user visits my website, the request goes to nodejs script running in my server. Now, can I process the request in NodeJS and then give a PHP file as a response (after processing on server side) instead of .html file

An outline of what I mean is:

Client Request-> NodeJS server->NodeJS script->PHP server->PHP script->Client Response

Its like stacking of 2 servers.

Why I was thinking of this..

I am making a social networking website where I already made most of my code in PHP and now I am working on real time communications where I do video/audio conferencing, text chat, etc. So, I am planning to use WebRTC and Websockets for this and found many websites telling that NodeJS is the best way to go about when taking Real Time communications to consideration.

But, if I have to do it, I have to change all my code from PHP to NodeJS which is not a good option. So, I thought why not run PHP server inside NodeJS server.

Thanks in advance

I did refer this question by the way: Recommendation for integrating nodejs with php application and felt my case is a bit different.

like image 286
Vignesh T.V. Avatar asked Aug 27 '15 11:08

Vignesh T.V.


4 Answers

PHP started it's earily life as a CGI. An HTTP Server would execute PHP script by spawning the PHP-CGI similarly to a command line application with all necessary data such as what would become $_GET, $_POST, and $_SERVER vars passed into the spawned CGI process as environmental variables. The CGI execution model had a high performance cost so later PHP implementations used either an embedded library such as Apache's HTTPD mod_php to execute PHP scripts directly in the HTTP server process or the PHP-FCGI SAPI which uses FastCGI protocol to execute PHP scripts outside of the HTTP server process as was originally required for IIS users on Windows. PHP-FCGI and the later and more preferred PHP-FPM SAPI are both standards now in high performance and high demand production HTTP/PHP services and both operate as a local daemon typically handling FCGI requests over IPC via Unix Domain Sockets (or local TCP sockets on windows). In other words, production HTTP services such as IIS, NGINX, and Apache HTTPD (if using mod_fcgi rather than mod_php) will typically execute PHP scripts using a built-in FCGI module/client to send FCGI requests into PHP-FCGI or PHP-FPM, executing the PHP script in a different process than the web server. This is also possible with Node.JS if you use a FCGI module such as node-phpfpm which allows node to make FCGI requests on PHP the same way as other modern high performance HTTP services. This approach allows node to execute PHP scripts as intended in production HTTP/PHP stacks, meaning it doesn't require the use of special daemons or secondary services (other than standard PHP-FCGI or PHP-FPM processes), doesn't require executing PHP in the same process space as the HTTP server, and it doesn't depend on executing long running PHP scripts to access requests over distributed queues or other messaging interfaces. In short it couples Node.JS with PHP on the exact level as NGINX or other "standard" HTTP/PHP services without using workarounds or custom protocols/interfaces. I would argue this to be the most proper as roughly 90% of the entire internet uses PHP over FCGI yet will still allow you to use much loved Node.JS code for other areas of your application.

Another option, such as if your looking for a more stateful PHP solution as opposed to just creating pages, is to use a queue or other messaging platform between Node.JS and a daemonized long running PHP script (examples ZMQ, Redis, AMQ, etc)

Lastly, you can always make requests from Node.JS onto a standard PHP enabled HTTP server somehow over HTTP such as Jose Mato suggested in his answer. This is option does not tie Node.JS and PHP together as the other options would, requires the additional resources and overhead of a second HTTP server on the network, and would require a custom protocol, but could be easier for some since this is how JavaScript has interfaced with PHP for well over a decade.

like image 185
JSON Avatar answered Sep 19 '22 20:09

JSON


Technically yes, you can, but, if you want to keep both applications I really recommend you create an interface (API) for you PHP app (eg: REST) and use it from NodeJS using the proper methods (eg: GET /profile)

If you just need to call to php server to centralize the authorization/authentication then you can find alternatives like sharing a Redis instance.

like image 38
Jose Mato Avatar answered Sep 18 '22 20:09

Jose Mato


The easiest way to achieve this is to run both Node.js and PHP on the same server, but on different ports. A node.js server can then just do a local HTTP request to the PHP server and do something with the response.

like image 44
Evert Avatar answered Sep 19 '22 20:09

Evert


yeah i know is 2 years older and just in case you want fire up nodejs with php in windows -i did in this way :

1.download PHP 8.1 (8.1.0alpha3) =VS16 x64 Non Thread Safe (2021-Jul-06 17:39:28) from https://windows.php.net/qa/

and unzip it in C:\x\php

2.put inside same location this php.ini more or less like this

engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
zend.exception_ignore_args = On
zend.exception_string_param_max_len = 0
expose_php = On
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off

display_startup_errors = Off

log_errors = On

ignore_repeated_errors = Off

ignore_repeated_source = Off

report_memleaks = On

variables_order = "GPCS"

request_order = "GP"
register_argc_argv = Off

auto_globals_jit = On

post_max_size = 8M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =

extension_dir = "c:\x\php\ext"
enable_dl = On

cgi.force_redirect = 1

fastcgi.impersonate = 1

cgi.rfc2616_headers = 1

file_uploads = On

upload_max_filesize = 2M

max_file_uploads = 20

allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60

extension=bz2
extension=curl
extension=fileinfo
extension=gd
extension=mysqli
extension=openssl
extension=sqlite3


[CLI Server]
cli_server.color = On


[Pdo_mysql]
pdo_mysql.default_socket=


[mail function]

SMTP = localhost
smtp_port = 25
mail.add_x_header = Off

[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1

[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
bcmath.scale = 0
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.cookie_samesite =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
zend.assertions = -1
tidy.clean_output = Off
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
ldap.max_links = -1

(i delete some stuff from it to be able to publish it here)

3.assuming on C:\n\ you have unzipped Windows Binary (.zip) got it from here https://nodejs.org/en/download/ and on your desktop you make a folder ..let say APP and inside you have runme.bat ,index.js ,favicon.ico and index.php :


runme.bat

c:\n\node.exe %CD%\index.js
pause

index.js

/*
these are codes from w3school and stackoverflow 
'cause am not even beginer in node.js (but i am fluent in JavaScript and others
,also i am programming since 1992 , almost 100 000 houres of programming in several languages)
*/
const http = require('http');
const url = require('url');
var fs = require('fs');
serialize = function(obj) {
var str = [];
for (var p in obj)
    
    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
    return str.join("&");
}

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});

        if (req.url === '/favicon.ico') {
        fs.readFile(__dirname + req.url, function (err,data) {
            if (err) {
                res.writeHead(404);
                res.end(JSON.stringify(err));
                return;
            }
            res.writeHead(200);
            res.end(data);
        });
        }

    const queryObject = url.parse(req.url,true).query;
    //console.log(`server 3 `  , queryObject);
    process.env.QUERY_STRING=serialize(queryObject);

    pathf=req.url.match('^[^?]*')[0].split('/').slice(1);
console.log(pathf);
const { exec } = require('child_process');
exec(`c:\\x\\php\\php-cgi.exe -c c:\\x\\php\\  %cd%\\index.php`, (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }stdout
 res.end(stdout);
});

}).listen(80); 

index.php

<?php
phpinfo();
//var_dump(get_defined_vars());
?>

so after you run runme.bat and in browser you have http://localhost/index.php?stack=overflow&its=cool&and=fun

you will be able to run php 8.1 alpha 3 from nodejs .. how you see inside index.js you have QUERY_STRING prepared for php and maybe others env vars are missing ... [IMPORTANT] THE SAME PHP.INI CONFIG I USE TO BUILD A NGINX WINDOWS SERVER TO CHECK YESTERDAY MY FASTEST PHP FRAMEWORK IN THE WORLD

YOU ARE FREE TO IMPROVE IT IF YOU KNOW JAVASCRIPT PROGRAMMING AND TO BUILD A SERVE FILES SECTION BASED ON THIS and maybe you approach to nginx features and so you no need several servers on several ports and minimum should sqlite 3 work already (just in case you can build around some stuff for localhost )

you see that pause inside runme.bat? it's only in case while you develop something in javascript and something goes wrong and it's crush ..so you will be able to hit enter to close it after you see the errors there.

like image 36
Constantin Avatar answered Sep 18 '22 20:09

Constantin