views:

107

answers:

1

I was needing a way to generate thumbnails (using PHP5) for an image management script and had a problem where my host has multiple versions of PHP installed (4 and 5), with PHP4 set as default. This meant that any calls to php from the CLI would run PHP4. I've come up with the following as what I hope to be a cross platform solution. I'm posting it here primarily as I had a lot of trouble finding any help using Google, so this might help someone in the future, I also have the following questions.

  1. Do you see anything obviously wrong with it?
  2. Are there any other paths to the php5 binary that you know of or know of a better order to have the array for optimisation?
  3. If a host has exec or shell_exec disabled, will the EGalleryProcessQueue.php script be able to be run as a standalone cron job? I don't have access to cron to be able to test this yet. I'm not too worried about this question, as I'll get around to testing it eventually anyway.
  4. Does anyone have any suggestions as to a way in which I can get some feedback as to how far through the images the processing is? See the TODO section of EGalleryProcessQueue.php I'd like to display a progress bar when it's in the admin section.

Main script

/**
 * Writes the array to a text file in /path/to/gallery/needsThumbs.txt for batch processing.
 * Runs the thumbnail generator script in the background.
 *
 * @param array $_needsThumbs the array of images needing thumbnails
 */
private function generateThumbnails($_needsThumbs)
{
    file_put_contents($this->_realpath.DIRECTORY_SEPARATOR.'needsThumbs.txt',serialize($_needsThumbs));

    $Command = realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR.'EGalleryProcessQueue.php '.$this->_realpath.' '.$this->thumbnailWidth.' '.$this->thumbnailHeight;

    if(PHP_SHLIB_SUFFIX == 'so')// *nix (aka NOT windows)
    {
        /*
         * We need to make sure we are using the right PHP version
         * (problems with shared hosts that have PHP4 and PHP5 installed,
         * but PHP4 set as default).
         */
        $phpPaths = array('php', '/usr/local/bin/php', '/usr/local/php5/bin/php', '/usr/bin/php', '/usr/bin/php5');
        foreach($phpPaths as $path)
        {
            exec("echo '<?php echo version_compare(PHP_VERSION, \"5.0.0\", \">=\"); ?>' | $path", $result);
            if($result)
            {
                shell_exec("nohup $path $Command 2> /dev/null > /dev/null &");
                break;
            }
        }
    }
    else // Windows
    {
        $WshShell = new COM("WScript.Shell");
        $WshShell->Run("php.exe $Command", 0, false);
    }
}

EGalleryProcessQueue.php

#!/usr/bin/php
<?php

if ($argc === 4 && strstr($argv[0], basename(__FILE__))) {
    // File is being called by the CLI and has not been included by another script

    if(!file_exists($argv[1].DIRECTORY_SEPARATOR.'needsThumbs.txt'))
    {
        // Either no thumbnails need to be created or a wrong directory has been supplied
        exit;
    }

    include(realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR.'EGalleryThumbGenerator.php');

    $generator = new EGalleryThumbGenerator;
    $generator->directory = $argv[1];
    $generator->thumbnailWidth = is_int($argv[2]) ? $argv[2] : 128;
    $generator->thumbnailHeight = is_int($argv[3]) ? $argv[3] : 128;

    // $generator->processImages() returns the number of images left to process (it does them in blocks of 10)
    while (($i = $generator->processImages()) > 0)
    {
        /*
         * TODO Can we get some sort of feedback to the user here?
         * Possibly so that we can display a progress bar in the management section.
         * Probably have to write $i to a file to be read by the main script.
         */
    }

    exit;
}
?>
+1  A: 

Do you see anything obviously wrong with it?

Nope, the code looks good.

Are there any other paths to the php5 binary that you know of or know of a better order to have the array for optimization?

This is a hard question to answer, as PHP could be installed anywhere on a server. The paths you have seem to be very logical to me, but there could be any number of other places it could be installed.

Rather than providing a bunch of directories where PHP5 might be installed, what about having a parameter the user has to set to provide the path to the PHP5 executable if it's not in their $PATH?

If a host has exec or shell_exec disabled, will the EGalleryProcessQueue.php script be able to be run via a cron job?

I haven't tested it, but I would assume that would prevent the script from running.

Does anyone have any suggestions as to a way in which I can get some feedback as to how far through the images the processing is? See the TODO section of EGalleryProcessQueue.php I'd like to display a progress bar when it's in the admin section.

Store the number of images completed somewhere (file, db, maybe even session var) and have an AJAX call fire every second or so to a function that provides done vs total. Then use something like http://docs.jquery.com/UI/Progressbar

bradym
Thanks. Yeh, I understand that PHP could be installed anywhere, I'm trying to cover the most likely locations. Good idea about the variable.Sorry, I meant being able to call the EGalleryProcessQueue.php script directly from cron (since the file should still be written, the exec/shell_exec calls will fail, but that shouldn't matter). Essentially, will EGalleryProcessQueue.php run fine as a stand alone cron job?Yeh, I had planned on using the jQuery UI progress bar. A session variable is a good idea.
Blair McMillan
Yes, you should be able to run the EGalleryProcessQueue.php directly from a cron job. PHP from the command line usually uses a different php.ini anyways, and you can force it to use a different php.ini with the -c flag. Type php -h from a command line to see the different flags.
bradym