9

What I want to do is simple in theory, but I cannot quite get it to work.

I wrote a simple node.js script that uses the request package to asynchronously fetch some data, parse it, and spit it out as html. I wanted to integrate this script in my client's php and apache based website which is on a shared host, and ran into some snags:

  1. There is no mod_proxy, so I can't simply run my node script as a server and proxy through Apache
  2. I don't want to run node on port 80 and proxy to apache from node. It's just way too much overkill for what I need to do, and would introduce too many headaches for me. My particular shared host is known to have trouble keeping node server instances up, and I can't justify potential downtime just for this script to run.
  3. I tried the node-cgi package but it didn't work for me. I got errors about internal node methods not existing, I think this package is just out of date.

So what I have landed on is trying to simply call node from PHP. My whole index.php file is:

<?php
  header("Content-Type: text/html");
  exec("node beerlist.nd", $output);
  echo implode('', $output);

When I execute php index.php on the command line, I get my expected output, however, when I try to access this from the browser, I get nothing ie Content-Length: 0. Why?

I thought maybe it had to do with the async nature of my node script but it seems like the process stays alive until it finishes all the async calls. So shouldn't my php snippet send the output to the browser without any trouble? What am I missing here?

Edit: This gist of my node script is

var req = require('request')

req("http://mywebsite.com", function(err, resp, body) {
  var output = // pull some interesting pieces out of the whole body
  console.log(output);
});

The generation of my output variable is not central to the issue here. The relevant parts are that I use request to make an asynchronous call and use console.log to output my results... maybe this is a problem?

parker.sikand
  • 1,371
  • 2
  • 15
  • 32
  • Does exec'ing `node beerlist.nd` yield a non-empty result? – Uli Köhler Feb 22 '14 at 18:58
  • 1
    If you mean doing `node beerlist.nd` on the command line, yes, it is non-empty. – parker.sikand Feb 22 '14 at 19:06
  • Well you are mixing two different technologies, wouldn't that be easier if your node program makes parsing and then over the http you get the results back ? This seems to be really hack solution and should be avoided. – Risto Novik Feb 22 '14 at 19:22
  • @jurka true, but I wrote the node script to work on a full node stack, and then wanted to use it on another apache/php site. This was the path of least resistance, and ended up working out just fine for me. – parker.sikand Feb 22 '14 at 22:55
  • FWIW, "lots of regexing and string functions on body" sets off alarm bells in my head. If you're dealing with HTML, you should use [a proper parser](https://github.com/MatthewMueller/cheerio), because [regexes aren't the right way to deal with HTML](http://stackoverflow.com/a/1732454/201952). – josh3736 Feb 22 '14 at 23:03
  • ...also, you probably should write directly to [`process.stdout`](http://nodejs.org/api/process.html#process_process_stdout) instead of using `console.log`. – josh3736 Feb 22 '14 at 23:05
  • 1
    `console.log` writes to stdout after minimal formatting http://stackoverflow.com/questions/4976466/difference-between-process-stdout-write-and-console-log-in-node-js... also, my string functions simply strip out white space and a few unwanted lines. The accepted answer worked for me. – parker.sikand Feb 23 '14 at 05:39
  • sry, I did leave out that I used the `cheerio` library to extract the HTML that I needed, the regex was just to remove whitespace – parker.sikand Feb 23 '14 at 05:40
  • also, I agree with what you said aout regexs not bein the "right" way to deal with HTML but what i needed in my case was super simple, and I don't think my regex was very unclear. (Besides, regex should be used ONCE in a while despite how confusing it may be) – parker.sikand Feb 23 '14 at 05:44
  • whether my regexes worked or not actually has nothing to do with my problem, as I stated that running the node script directly does exactly what it was supposed to do. – parker.sikand Feb 23 '14 at 05:47
  • 1
    @parker.sikand: Yes, I know that `console.log` also goes to stdout, but *after* doing other things that you don't necessarily have control over. It's also (marginally) slower due to the overhead of doing those things. Finally, using `process.stdout.write` makes it crystal clear to someone reading your code that you **intend** to output data on stdout and it's not just a debugging line (which is usually what `console.log` is) that got left in the code. – josh3736 Feb 24 '14 at 03:08

1 Answers1

8

I suppose Apache user doesn't know what node command is. If I'm right try to write in php file:

<full path to node> beerlist.nd

instead of

node beerlist.nd

To get full path to node run in terminal which node

Oleg
  • 22,300
  • 9
  • 68
  • 84
  • As a note, using Bluehost shared hosting, calling an unknown executable from PHP does not yield an error line, so be careful! – parker.sikand Feb 23 '14 at 05:48
  • 1
    Is there a way to get full path to node in php rather than in terminal? This way I won't need to update my php file every time I upgrade nodejs or push to a production server. – smohadjer Mar 14 '17 at 11:13
  • @smohadjer, you could try to execute this command in PHP: `"$(which node)" beerlist.nd`. See e.g. https://stackoverflow.com/q/3437514/1079869 for more info. – Matias Kinnunen Dec 29 '17 at 08:14