Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3336816
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T00:10:50+00:00 2026-05-18T00:10:50+00:00

I have a card game (screenshot below) in which I display player avatars. For

  • 0

I have a card game (screenshot below) in which I display player avatars.

For the avatars I’ve written a short proxy.php script, which would take an image URL passed to it as ?img= parameter, download it and save under /var/www/cached_avatars/md5_of_that_url at my CentOS 5 machine. Next time the script is called with the same URL, it will find that image in the dir and serve it directly to STDOUT.

This works mostly well, but for some avatars the initial download fails (I suppose it times out) and you don’t see the lower part of the player picture:

alt text

I’d like to detect this image download failure and delete the cached partial file, so that it is re-downloaded on the next proxy.php call.

I’ve tried detecting STREAM_NOTIFY_FAILURE or STREAM_NOTIFY_COMPLETED events in my callback, but they are not fired. The only events I see are: STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_MIME_TYPE_IS, STREAM_NOTIFY_FILE_SIZE_IS, STREAM_NOTIFY_REDIRECTED, STREAM_NOTIFY_PROGRESS:

Nov  3 18:48:27 httpd: 2  0
Nov  3 18:48:27 httpd: 4 image/jpeg 0
Nov  3 18:48:27 httpd: 5 Content-Length: 45842 0
Nov  3 18:48:27 httpd: 7  0
Nov  3 18:48:27 last message repeated 16 times
Nov  3 18:48:39 httpd: 2  0
Nov  3 18:48:40 httpd: 4 image/jpeg 0
Nov  3 18:48:40 httpd: 5 Content-Length: 124537 0
Nov  3 18:48:40 httpd: 7  0

And my even bigger problem is, that I can’t pass variables like $img or $cached into the callback or I can’t set a $length variable in the callback on a STREAM_NOTIFY_FILE_SIZE_IS event and then compare it with filesize($cached) in the main script (I could detect the mismatch and delete the file):

Nov  3 18:50:17 httpd: PHP Notice:  Undefined variable: length in /var/www/html/proxy.php on line 58
Nov  3 18:50:17 httpd: length=

Does anybody have a solution for my problem?

I’ve looked at the PHP curl library, but don’t see how could it help me here.

Below is my script, I’ve omitted the URL sanity checks for brevity:

<?php

define('MAX_SIZE', 1024 * 1024);
define('CACHE_DIR', '/var/www/cached_avatars/');

$img = urldecode($_GET['img']);

$opts = array(
        'http' => array(
                'method' => 'GET'
        )
);

$cached = CACHE_DIR . md5($img);

$finfo = finfo_open(FILEINFO_MIME);
$readfh = @fopen($cached, 'rb');
if ($readfh) {
        header('Content-Type: ' . finfo_file($finfo, $cached));
        header('Content-Length: ' . filesize($cached));

        while (!feof($readfh)) {
                $buf = fread($readfh, 8192);
                echo $buf;
        }

        fclose($readfh);
        finfo_close($finfo);
        exit();
}

$ctx = stream_context_create($opts);
stream_context_set_params($ctx, array('notification' => 'callback'));
$writefh = fopen($cached, 'xb');
$webfh = fopen($img, 'r', FALSE, $ctx);
if ($webfh) {
        $completed = TRUE;

        while (!feof($webfh)) {
                $buf = fread($webfh, 8192);
                echo $buf;
                if ($writefh)
                        fwrite($writefh, $buf);
        }

        fclose($webfh);
        if ($writefh)
                fclose($writefh);

        # XXX can't access $length in callback
        error_log('length=' . $length);

        # XXX can't access $completed in callback
        if (!$completed)
                unlink($cached);
}

function callback($code, $severity, $message, $message_code, $bytes_transferred, $bytes_total) {
        error_log(join(' ', array($code, $message, $message_code)));

        if ($code == STREAM_NOTIFY_PROGRESS && $bytes_transferred > MAX_SIZE) {
                exit('File is too big: ' . $bytes_transferred);

        } else if ($code == STREAM_NOTIFY_FILE_SIZE_IS) {
                if ($bytes_total > MAX_SIZE)
                        exit('File is too big: ' . $bytes_total);
                else {
                        header('Content-Length: ' . $bytes_total);
                        # XXX can't pass to main script
                        $length = $bytes_total;
                }

        } else if ($code == STREAM_NOTIFY_MIME_TYPE_IS) {
                if (stripos($message, 'image/gif') !== FALSE ||
                    stripos($message, 'image/png') !== FALSE ||
                    stripos($message, 'image/jpg') !== FALSE ||
                    stripos($message, 'image/jpeg') !== FALSE) {
                        header('Content-Type: ' . $message);
                } else {
                        exit('File is not image: ' . $mime);
                }
        } else if ($code == STREAM_NOTIFY_FAILURE) {
                $completed = FALSE;
        }
}

?>

I don’t use any file locking in my script: it’s ok for a read from cache to return an incomplete file (because it is still being downloaded) once in a while. But I want to keep my cache free of any partially downloaded images. Also if you look at my script I use “xb” which should prevent from several scripts writing into 1 file, so this simultaneous writing is not a problem here.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T00:10:51+00:00Added an answer on May 18, 2026 at 12:10 am

    The curl library is what you would want to us to download the image. It handles timeouts, redirects and error checking. For example, you can check for a 404 (missing file) response from the server you are connecting to. If everything works, then you write the contents to a cache file using fopen.

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_URL, $img_url);
    $content = curl_exec($ch);
    $info = curl_getinfo($ch);
    $errorCode      = curl_errno($ch);
    $errorMsg       = curl_error($ch);
    curl_close($ch);
    // Check for errors
    if ( $errorCode==0 ) {
        // No connection errors, just for response type
        if ($info['http_code'] != 200) {
            // Something happened on the other side
            ...
        } else {
            // Image is in $content variable, save to cache file
            ...
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a PHP-script listing up to 20 card game players per page: I
I am making a card game in ruby. I have the Game class, which
I have a card-game application which makes use of Single Table Inheritance. I have
I have a small card game for Google+ which needs the visitor's name, avatar,
I have a Rails 2.3.5 app which is serving a card game. I've been
So, i'm attempting simple card game. I have player class with draw function, and
I have a card game - written in Perl and with few objects, like
I have a small card game at Facebook (and few Russian social networks), which
I have a card game on the iphone and I really would like to
I have a card game in java. I would like to play a sound

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.