tags:

views:

926

answers:

9

I have a method to save an image, which is meant to deal gracefully with an error, setting $imageSrc to a particular image in the event of failure. My method works fine if the image is present, but no error conditions seems to be handled correctly.

$imageSrc = save_pic($PIC_URL, $pk);

function save_pic($pic_url, $pk) {
    $imageDir = './';
    if (!strlen($pic_url))
            return "removed.jpg";
    if (!is_dir($imageDir) || !is_writable($imageDir)) {
     return "removed.jpg";
    }
    $image = file_get_contents($pic_url);
    if (empty($image)) {
     return "removed.jpg";
    }
    $r = file_put_contents($imageDir.$pk.".jpg", $image);
    if ($r) {
            return "./$pk.jpg"; 
    } else {
            return "removed.jpg";
    }
}

If the image does not exist, I get :

Warning: getimagesize(http://127.0.0.1/555.jpg) [function.getimagesize]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in C:\Program Files\EasyPHP 2.0b1\www\get_auction.php on line 144

Array (
 [type] => 2 [message] => getimagesize(http://127.0.0.1/555.jpg)
 function.getimagesize]: failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 [file] => C:\Program Files\EasyPHP 2.0b1\www\get_auction.php
 [line] => 144
) 1

returned.jpg is never returned in any event.

edit: added imageResize code:

function imageResize($imageURL, $maxWidth, $maxHeight)

{

global $outputWidth, $outputHeight, $maxWidth, $maxHeight;

$size = getimagesize($imageURL);

if ($size) {

    $imageWidth  = $size[0];

    $imageHeight = $size[1];

    $wRatio = $imageWidth / $maxWidth;

    $hRatio = $imageHeight / $maxHeight;

    $maxRatio = max($wRatio, $hRatio);



    if ($maxRatio > 1) {

        $outputWidth = $imageWidth / $maxRatio;

        $outputHeight = $imageHeight / $maxRatio;

    } else {

        $outputWidth = $imageWidth;

        $outputHeight = $imageHeight;

    }

} else {

    die(print_r(error_get_last()));

}

}
A: 

Are you sure you're writing to the root folder? Because I can't see any problem with your code. file_get_contents and file_put_contents don't seem to be failing, so your image is being written somewhere.

Can Berk Güder
but it doesnt deal with the file not existing in order to get
Joshxtothe4
so file_get_contents *should* return FALSE but doesn't, is that correct?
Can Berk Güder
Exactly, The problem is not with the folder being writable, but with the image not existing at the url
Joshxtothe4
A: 
 $image = file_get_contents("http://example.com/test.png");
 list($ver, $retcode, $message) = explode(' ', $http_response_header[0], 3);
 if ($retcode != 200) {
   return "removed.jpg";
 }

$retcode will contain HTTP response code.

Please post this $retcode here and what your strlen($image) returns, it might help to resolve your problem.

Quassnoi
the error code is 404, it states it in the error message
Joshxtothe4
Yes, and he can parse it in the code.
Quassnoi
I put this in my code as you suggest, and only the file_Get_contens error is output, nothing after that.
Joshxtothe4
Does it ever get after file_get_contents? Put an echo right after file_get_contents and see if it gets there.
Quassnoi
ah... the wonder that is debugging PHP
Dominic Rodger
A: 

Try this:

<?php
$imageSrc = save_pic($PIC_URL, $pk);

function save_pic($pic_url, $pk) 
{
    $imageDir = './';

    if (!strlen($pic_url))
    {
        return 'removed.jpg';
    }

    if(!is_dir($imageDir) || !is_writable($imageDir)) 
    {
        return 'removed.jpg';
    }

    if(!file_exists($pic_url))
    {
        return 'removed.jpg';
    }

    if (file_put_contents($imageDir . $pk . '.jpg', file_get_contents($pic_url))) 
    {
            return $imageDir . $pk . '.jpg'; 
    } 
    else 
    {
            return 'removed.jpg';
    }
}
Bart S.
Hi Bart, this had the same exact behavior.
Joshxtothe4
Can you post the code from C:\Program Files\EasyPHP 2.0b1\www\get_auction.php around line 144?Because that is what's causing this error:C:\Program Files\EasyPHP 2.0b1\www\get_auction.php on line 144
Bart S.
line 144 is just $imageSrc = save_pic($PIC_URL, $pk);
Joshxtothe4
A: 

Debug?

Get an IDE that includes a debugger, like Eclipse or Netbeans, rtm for functions to see how the respond, or do bad-old inline debugging to echo the value of code at runtime.

+1  A: 

It seems to me you're not posting your complete code?

The warning message says getimagesize(), yet nowhere is getimagsize() used in your example. To receive better help I would include the whole method or an updated error message of your current efforts. Please also include the PHP version you're using.

file_get_contents() will return false in case of errors and does so on 404 HTTP errors, as demonstrated:

mfischer@testing01:~$ php -r 'var_dump(file_get_contents("http://stackoverflow.com/i_do_not_exist.jpg"));'

Warning: file_get_contents(http://stackoverflow.com/i_do_not_exist.jpg): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in Command line code on line 1

Call Stack:
    0.0002      51884   1. {main}() Command line code:0
    0.0002      51952   2. file_get_contents() Command line code:1

bool(false)
mfischer@testing01:~$ php -v
PHP 5.2.6-5 with Suhosin-Patch 0.9.6.2 (cli) (built: Oct  5 2008 13:07:13)

Trying out your code it works perfectly fine for me here:

$ cat test.php
<?php
$PIC_URL="http://stackoverflow.com/i_dont_exist.jpg";
$pk = "test";
$imageSrc = save_pic($PIC_URL, $pk);
var_dump($imageSrc);

function save_pic($pic_url, $pk) {
    $imageDir = './';
    if (!strlen($pic_url))
            return "removed.jpg";
    if (!is_dir($imageDir) || !is_writable($imageDir)) {
        return "removed.jpg";
    }
    $image = file_get_contents($pic_url);
    if (empty($image)) {
        return "removed.jpg";
    }
    $r = file_put_contents($imageDir.$pk.".jpg", $image);
    if ($r) {
            return "./$pk.jpg";
    } else {
            return "removed.jpg";
    }
}
$ php test.php

Warning: file_get_contents(http://stackoverflow.com/i_dont_exist.jpg): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
 in /home/mfischer/tmp/532480/test.php on line 14

Call Stack:
    0.0005      59824   1. {main}() /home/mfischer/tmp/532480/test.php:0
    0.0005      60176   2. save_pic() /home/mfischer/tmp/532480/test.php:4
    0.0006      60444   3. file_get_contents() /home/mfischer/tmp/532480/test.php:14

string(11) "removed.jpg"

PHP functions have the bad habit of just spilling out warning messages right in your code, if you don't like this you can silence them with the '@' operate as suggested before or you can alternatively use a HTTP Client library as provided by PEAR_HTTP or Zend_HTTP_Client to have better control of error handling. Rolling your own thing with sockets, fsockopen, etc. would also be possible.

But back to the point: if it's still not working, I think there's some information missing.

mark
I have updated my question to show the ImageResize function. The problem seems to be with the 404 error however.
Joshxtothe4
A: 

Should you not be testing for file_get_contents errors? I mean with something like

if( false == ($image = file_get_contents($pic_url))){
        return "removed.jpg";
    }
Jack
A: 
  • Send HTTP HEAD to given URL
  • Check returncode == 200 (file is there) else it's removed
  • Check that Content-Type header is image/* (for example image/png) else it's removed
  • If server sent Content-Length header, read that to variable
  • file_get_contents(URL)
  • If server sent that Content-Length see if size matches else it's removed
  • Save image
  • Try getimagesize(), if it gives errors remove it via unlink() and it's removed else keep it
  • Success!
raspi
A: 

You are having path issues. You should store the full path to the pic in a define.

Make sure this file is sourced from the save_pic function.

DEFINE("RemovedPicUrl", "http://" . $_SERVER['SERVER_NAME'] . "/path/to/removed/image/removed.jpg")

then change all occurances of

"Removed.jpg"

to

RemovedPicUrl

And I'll bet you a dollar that fixes your issue.

Byron Whitlock
A: 

The problem was not a code issue, but was caused by file corruption. This was determined while testing on other machines.

Joshxtothe4