Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting Dynamic Page Contents

Status
Not open for further replies.

DonP

IS-IT--Management
Jul 20, 2000
684
US
I am trying to reuse a function on a new site that works perfectly on one of my others but not on the new one. On the index.php page, there is some code that saves a couple values as sessions:

Code:
$ServerName = $_SERVER['SERVER_NAME'];
$ScriptName = $_SERVER['SCRIPT_NAME'];
$QueryString = "?TabID=6";
$_SESSION['PrintVersionPath'] = $ServerName . $ScriptName . $QueryString;
$_SESSION['PrintVersionParam'] = $QueryString;
So, for example, the sessions might contain:

PrintVersionPath = localhost/index.php?TabID=6
PrintVersionParam = ?TabID=6


Then the function itself, which is on a print_page.php script, grabs these values and should open the same database entry, but it is breaking on the implode() function so clearly it is not getting the page data from these values. I did not write the function so I do not fully understand how it works but here it is:

Code:
function getFile($host, $query) {
   $path=explode('/',$host);
   $host=$path[0];
   unset($path[0]);
   $path = $host;
   $path='/'.(implode('/',$path));
   $post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\nUser-Agent:[/URL] Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
   $h=fsockopen($host,80);
   fwrite($h,$post);
   for($a=0,$r='';!$a;){
      $b=fread($h,8192);
      $r.=$b;
      $a=(($b=='')?1:0);
   }
   fclose($h);
   return $r;
}
Of course there's other code to bring it to the screen but the issue seems to be in the function itself which, as I said, works perfectly on another site.

I already tried:

Code:
$ServerName = $_SERVER['SERVER_NAME'];
$ScriptName = $_SERVER['SCRIPT_NAME'];
$QueryString = "?".CCGetQueryString("All", "");
$_SESSION['PrintVersionPath'] = $ServerName;
$_SESSION['PrintVersionParam'] = $ScriptName . $QueryString;
to give the session values:

PrintVersionPath = localhost
PrintVersionParam = /index.php?TabID=6


then removing the explode() and implode functions and it no longer gives errors but neither does it bring up the page. Does anyone see a solution as to what's wrong?

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
is this the warning you are getting?
Warning: implode() [function.implode]: Bad arguments. in ... page.php on line XX


If so:
Its breaking in the implode function because the variable
its trying to implode is no longer an array.
Code:
$path=explode('/',$host);
   $host=$path[0];
   unset($path[0]);
[red]   $path = $host;[/red]

You probably got by it in your other servers, because the error reporting level is lower than in the current one. The lower level makes them ignore warnings, so it just keeps going.

Maybe a simple string concatenation would work better there.






----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.
 
Makes sense and yes that's the error although it's not clear to me why it needs to explode() or implode() at all. Feeding the function:

PrintVersionPath = localhost
PrintVersionParam = /index.php?TabID=6


should eliminate the need, shouldn't it? That said, I simplified the function to:

Code:
function getFile($host, $query) {
   $path = $host;
   $post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\nUser-Agent:[/URL] Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";
   $h=fsockopen($host,80);
   fwrite($h,$post);
   for($a=0,$r='';!$a;){
      $b=fread($h,8192);
      $r.=$b;
      $a=(($b=='')?1:0);
   }
   fclose($h);
   return $r;
}
and gave a variable to the results and echoed what it thinks it's getting so that I could see it (before, this came up empty):

Code:
$PageCode = getFile($_SESSION['PrintVersionPath'], $_SESSION['PrintVersionParam']);

echo $PageCode
Now it gives an error that makes sense so it seems that with these changes it is losing it at the POST:

Code:
HTTP/1.1 400 Bad Request
Server: Microsoft-IIS/5.1
Date: Fri, 20 Apr 2007 18:30:30 GMT
Connection: close
Content-Type: text/html
Content-Length: 87
Thanks for your help and ideas! Any further thoughts?

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
Probably has something to do, with the $path variable, but since I'm no expert at modifying POST query strings, I'm not sure i can be of much help.

Although maybe its expecting just the first part of the host variable.

what if you do:
Code:
 $path = "localhost";
   $post="POST $path HTTP/1.1\r\nHost: $host\r\nContent-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\nUser-Agent:[/URL] Mozilla 4.0\r\nContent-length: ".strlen($query)."\r\nConnection: close\r\n\r\n$query";

does it work then?

----------------------------------
Ignorance is not necessarily Bliss, case in point:
Unknown has caused an Unknown Error on Unknown and must be shutdown to prevent damage to Unknown.
 
Thanks for the idea but I had tried that already at some point. It gives errors on fsockopen() with the errors: "No such host is known" and "unable to connect to localhost/index.php:80 (Unknown error)".

For fwrite(), fread() and fclose() the error is "supplied argument is not a valid stream resource".

I am reasonably sure that you're right, the error is somewhere in the POST but I can't find out much info and am not sure what it is expecting for the values.

Right now I am trying hard-coding the values passed to the function in order to make testing easier. With:

Code:
$PageCode = getFile("localhost", "index.php?TabID=6");

echo $PageCode;
or

Code:
$PageCode = getFile("localhost", "/index.php?TabID=6");

echo $PageCode;
it echos the error: "HTTP/1.1 400 Bad Request Server: Microsoft-IIS/5.1 Date: Fri, 20 Apr 2007 21:55:54 GMT Connection: close Content-Type: text/html Content-Length: 87 The parameter is incorrect." but it's not clear which paramater is incorrect. I am trying other variations.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
After trying several variations and researching on php.net (the search engine is still dead on tek-tips), I am now getting only "Resource id #53" when echoing to the screen. Also, it appears that the explode()/implode() functions are there because the code was expecting a full path, not just simply the host.

Basically these two seem to be the same and give identical results but maybe someone can clarify:

called with getFile("localhost/index.php?TabID=6", "/index.php?TabID=6");
Code:
function getFile($host, $query, $others='') {
   [COLOR=blue]$path=explode('/',$host);
   $host=$path[0];
   unset($path[0]);
   $path='/'.(implode('/',$path));
   $out  = "POST $path HTTP/1.1\r\n";[/color]
   $out .= "Host: ".$host."\r\n";
   $out .= "Content-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\n${others}";[/URL]
   $out .= "User-Agent: Mozilla 4.0\r\n";
   $out .= "Content-length: ".strlen($query)."\r\n";
   $out .= "Connection: Close\r\n\r\n$query";
   $fp = fsockopen($host, 80, $errno, $errstr, 30);
   fwrite($fp, $out);
   for($a=0,$r='';!$a;){
      $b=fread($fp,8192);
      $r.=$b;
      $a=(($b=='')?1:0);
   }
  fclose($fp);
 return $fp;
}

called with getFile("localhost", "/index.php?TabID=6");
Code:
function getFile($host, $query, $others='') {
   [COLOR=blue]$out  = "POST / HTTP/1.1\r\n";[/color]
   $out .= "Host: ".$host."\r\n";
   $out .= "Content-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\n${others}";[/URL]
   $out .= "User-Agent: Mozilla 4.0\r\n";
   $out .= "Content-length: ".strlen($query)."\r\n";
   $out .= "Connection: Close\r\n\r\n$query";
   $fp = fsockopen($host, 80, $errno, $errstr, 30);
   fwrite($fp, $out);
   for($a=0,$r='';!$a;){
      $b=fread($fp,8192);
      $r.=$b;
      $a=(($b=='')?1:0);
   }
  fclose($fp);
 return $fp;
}
The above was gleaned from my original code and various examples on php.net.

It's not clear to me why it might be better to pass the entire path, then explode it apart to get the host rather than just passing only the host in the first place. It is also not clear what the last parameter $others is for as it seems to be doing nothing that I can see. Can someone help and tell me what the output "Resource id #53" means? Thanks!

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
the resource you are getting is a resource handle. this is the link that php maintains with the socket you have opened in fsockopen.

if you want the results of the freads, then i would return $r rather than $fp.
 
Thanks, you're right. Changed to $r it outputs:

HTTP/1.1 100 Continue Server: Microsoft-IIS/5.1 Date: Mon, 23 Apr 2007 17:29:24 GMT HTTP/1.1 405 Method not allowed Server: Microsoft-IIS/5.1 Date: Mon, 23 Apr 2007 17:29:24 GMT Connection: close Allow: OPTIONS, TRACE, GET, HEAD Content-Length: 3923 Content-Type: text/html The page cannot be displayed

so I tried changing the method to GET which seems to start a new session each time, setting a cookie for it, and outputs:

HTTP/1.1 200 OK Server: Microsoft-IIS/5.1 Date: Mon, 23 Apr 2007 17:31:13 GMT Connection: close X-Powered-By: PHP/5.2.1 Set-Cookie: PHPSESSID=3g1tp0rs7l1fe2l2optb3no6p7; path=/ Pragma: Cache-control: Expires: Content-Type: text/html; charset=utf-8

I don't want it to set a cookie or begin a new session!

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
I think this function (from php.net) might do what I need, however, it seems to try to open the page in a new session rather than keeping the existing one. Is there a way around this? Just to be clear, what I am trying to do it to grab the resulting dynamic HTML, not load the page itself into the browser. Thanks!

Code:
function getFile($server, $file) {
   $cont = "";
   $ip = gethostbyname($server);
   $fp = fsockopen($ip, 80, $errno, $errstr, 30);
   if (!$fp) {
      return "Unknown";
   } else {
      $com = "GET $file HTTP/1.1\r\n";
      $com .= "Accept: */*\r\n";
      $com .= "Accept-Language: en-us\r\n";
      $com .= "Accept-Encoding: gzip, deflate\r\n";
      $com .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n";
      $com .= "Host: $server:80\r\n";
      $com .= "Connection: Keep-Alive\r\n\r\n";
      fputs($fp, $com);
      while (!feof($fp)) {
         $cont .= fread($fp, 500);
      }
      fclose($fp);
      $cont = substr($cont, strpos($cont, "\r\n\r\n") + 4);
     return $cont;
   }
}

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
would you not be better off using the cURL functions?
 
Possibly, although I tried another function that used it and got nowhere. I am working currently on a Windows XP development system but I am not sure that CURL is part of the actual server's configuration, unless it is a standard part of PHP 5's installation. Otherwise I know less than nothing about CURL.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
look at phpinfo() to determine what modules you have loaded.

what are you actually trying to achieve here?
 
Thanks, yes, I have already done that. CURL is here on my development system but it is not on the server and I do not have access to put it there.

I use this code to create printable versions of pages and it works without reguard to the original page script, database or SQL by grabbing the dynamic contents, then fetching from it the text that is between a pair of <!--print--> tags. A print_page.php then cleans up the resulting HTML, adds new <html>, <head> and <body> tags to it, and applies a new style sheet for printing.

That said, I tried the most recent version on my other server, which is Linux, and it does not run there either while the working version there does not work here on IIS5.

On the site where it works, the page being printed contains:

Code:
$ServerName = $_SERVER['HTTP_HOST'];
$ScriptName = $_SERVER['SCRIPT_NAME'];
$QueryString = "?". $QueryString;
$_SESSION['PrintVersionPath'] = $ServerName . ScriptName . $QueryString);;
$_SESSION['PrintVersionParam'] = $QueryString;
The sessions it creates contain something like:
PrintVersionPath: localhost/index.php?TabID=6
PrintVersionParam: ?TabID=6


The function on the print_page.php script has:

Code:
function getFile($host,$query){
   $path = explode("/",$host);
   $host = $path[0];
   unset($path[0]);
   $path = "/".(implode("/",$path));
   $post  = "POST $path HTTP/1.1\r\n";
   $post .= "Host: $host\r\n";
   $post .= "Content-type: application/x-[URL unfurl="true"]www-form-urlencoded\r\n";[/URL]
   $post .= "User-Agent: Mozilla 4.0\r\n";
   $post .= "Content-length: ".strlen($query)."\r\n";
   $post .= "Connection: close\r\n\r\n$query";
   $h=fsockopen($host,80);
   fwrite($h,$post);
   for($a = 0, $r = "";!$a;){
       $b = fread($h,8192);
       $r .= $b;
       $a = (($b == "")?1:0);
   }
   fclose($h);
   return $r;
}

$PageCode = getFile($_SESSION['PrintVersionPath'], $_SESSION['PrintVersionPath'];
This is essentially what I posted originally but it was cleaned up a little and tested last night on the original Linux system where it still works perfectly. On the new IIS site, it does not work.

These is further code that removes links, forms and JavaScript and cleans up the HTML for printing as mentioned above.

On IIS, it errors with:

HTTP/1.1 100 Continue Server: Microsoft-IIS/5.1 Date: Tue, 24 Apr 2007 15:32:55 GMT HTTP/1.1 405 Method not allowed Server: Microsoft-IIS/5.1 Date: Tue, 24 Apr 2007 15:32:55 GMT Connection: close Allow: OPTIONS, TRACE, GET, HEAD Content-Length: 3923 Content-Type: text/html
The page cannot be displayed


Since it is erroring on the Method and indicates that only OPTIONS, TRACE, GET, HEAD are allowed, I tried changing it to GET but then it gives a new session which forces a login as these pages are secured. Not SSL but protected from casual eyes on an Intranet site. Could there be some php.ini setting of something that needs to be enabled that is causing it? If so, I've not been able to locate it:

HTTP/1.1 200 OK Server: Microsoft-IIS/5.1 Date: Tue, 24 Apr 2007 15:39:50 GMT Connection: close X-Powered-By: PHP/5.2.1 Set-Cookie: PHPSESSID=doorl2ml6cch138hmeqkr9hhd0; path=/ Pragma: Cache-control: Expires: Content-Type: text/html; charset=utf-8

Thanks again for your help.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
I am reasonably sure that the problem is to do with fsockopen() as it does not appear to be compatible with IIS. However, fopen() does no better. Are there any thoughts on this?

Code:
$h = fsockopen($host,80);
   //$h = fopen("[URL unfurl="true"]http://".$host."/index.php".$query);[/URL]
   fwrite($h, $post);
   for($a = 0, $r = ""; !$a;){
   $b = fread($h,8192);
   $r .= $b;
   $a = (($b == "")?1:0);

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
i do not of any incompatibility between fsockopen and IIS. i have used them together with no problems that i recall.

try performing your get requests manually in a terminal and see what the returns are.

 
What I am seeing is that apparently fsockopen() is working but something in the function is causing it to lose the session so it starts a new one. The new one triggers the login page which is all I can get through the function in IIS. On my other Linux server, this does not seem to be an issue but this site needs to run on IIS.

Although years ago I used to test Perl in telnet, I have never used terminal to do so with PHP. How it is done? Thanks.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
fsockopen does not send cookie data and you will probably need to send the cookie to the foreign site to be able to continue the session. i would use CUrl to do this but you say this is not possible.

does the foreign site support the transmission of the session ID as part of the query string?
 
I should be able to program it to do so but isn't that a security issue?

On the other hand, presuming that I could somehow get Curl onto the server, I have never used it before so what do I need to do to the function in order for it to work? I've never used Curl before but it sounds like it might be the way to go.

Don
Experienced in HTML, Perl, PHP, VBScript, PWS, IIS and Apache and MS-Access, MS-SQL, MySQL databases
 
i think you will find it difficult to use cUrl if your host has not compiled it into their php offering.

you could code the GET/POST request yourself, as you are doing above, but you need to include the cookie headers too, and do so manually. in that way the remote site can identify the session.

so the route would be something like:

1. hit the page first with a GET request.
2. parse the cookie data and store it
3. for each subsequent hit, reuse that parsed cookie data in the request that you send.

this is not too complex, but it is manual... you may want to consider using some pre-built classes such as Http_Client from pear.php.net (this is a wrapper for HTTP_Request, also from pear).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top