tags:

views:

35

answers:

2

I am struggling with PHP's GD library.

I have written a script called foo.php which outputs a png:

header('Content-type:image/png');
$img = imagecreatefrompng($url) or die('bad url:'.$url);
imagepng($img);
imagedestroy($img);

It works fine. Its purpose is to accept a GET parameter and then spit out the appropriate graph:

(e.g.) foo.php?id=2 puts a nice graph in any browser.

Here's my problem:

In another script (baz.php), I'd like to use readfile or something similar to take the image created by foo.php and have baz.php send it to the browser. But no matter what I try, it won't seem to work when I call baz.php

Example from baz.php:

switch($id) {
    case '1':
         readfile('foo.php?id=1');
         break;
    case '2':
         readfile('foo.php?id=2');
         break;
    // and so on...
}

I get an error saying:

failed to open stream: No such file or directory...

If I put in the full url or the path:

readfile('http://localhost/dev/foo.php?id=1');
readfile('C:/xampp/htdocs/dev/foo.php?id=1');

...I get the same error.

If I add the header to baz.php:

header('Content-type:image/png');
readfile($url);

In firefox I get "The image "http://localhost/dev/baz.php" cannot be displayed, because it contains errors. In Chrome it shows a broken image 27.82kb in size with dimensions of 0x0

*allow_url_fopen* is on, and as I mentioned, foo.php is producing pngs without any problems; I just can't seem to get in out of baz.php, which I need to.

I can, for instance just put:

header("Location: foo.php?id=1");

and it will redirect and output the image, but I don't want to do a 302 redirect, I need baz.php to push the image out to the browser. If I save the file as a static file, it will load that fine as well. It just doesn't seem to want to handle the dynamic file.

Any help is very much appreciated. Thanks in advance.

A: 

this should work http://theserverpages.com/php/manual/en/function.imagecreatefrompng.php

Nurul Ferdous
@nurul - it's a little nicer debugging, but it's still the same problem - it won't open the file if it's dynamic (LoadPNG will give "error loading" and the filename 'localhost/dev/foo.php?id=1', which, if I paste it into the browser (with or without the http) loads fine.
TMG
A: 

Figured it out:

Issue #1:

You cannot use php's readfile() to include a png that is generated dynamically by php if it is on the same server.

Why? Because readfile will include the raw php code rather than rendering that php code into an image. If you want to call it from another server, readfile works fine.

So, you can include/require the file instead (so it will be rendered into a png), however...

Issue #2:

You cannot include a file with parameters / query string directly (e.g. the following code will error that it cannot open the file:

include('baz.php?id=1'); //this won't work

Solution:

  • Set the parameter manually in the GET string (e.g. $_GET['id'] = 1;)
  • Include the file: include('baz.php');

*Also note: Apache's virtual() command will also not work with GET because only QUERY_STRING is passed along ($_GET is copied from the parent script):*

PHP.net's description of virtual()

TMG
It's great of you to post the solution (I wish everybody did that!), but your conclusions are incorrect, sorry :) `readfile will include the raw php code rather than rendering that php code into an image` it will *definitely* work from *any* location, including the same server, if you specify a `http://` path. If it does, something is seriously wrong with your configuration! Just note that `localhost` always points to the same machine (it's a synonym for 127.0.0.1 and *not* a valid host name).
Pekka
@Pekka: It should, but **did you try it?** Even with a wrapper it does not work on the same server for me: (Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9) Here's some test code:<?PHP //foo.php$url = 'http://chart.apis.google.com/chart?cht=p3$url = 'http://localhost/dev/baz.php';readfile($url);?><?PHP //baz.phpheader('Content-type: image/png');$url = 'http://chart.apis.google.com/chart?cht=p3$img = imagecreatefrompng($url);imagepng($img);imagedestroy($img);?>
TMG
Ack - SO nerf'd my code in the comment again. Bottom line is, I tried it with a wrapper and it does not work on the same server. There are scattered mentions of it I found googling (e.g. http://www.bluehostforum.com/showthread.php?4620-Calling-PHP-function-readfile()-on-own-domain-fails)
TMG
@TMG really, really strange - have never encountered this before. I can't try this out right now - if I get around to it in the next couple of days, I'll give feedback.
Pekka