PHP 7.0.9上的fseek

时间:2017-05-11 03:13:09

标签: php fseek

我有一个适用于PHP 5.6.30的代码,但是在PHP 7.0.9上它显示错误:

  

致命错误:超过30秒的最长执行时间   第152行的D:\ xampp \ htdocs \ myaac \ system \ libs \ items.php

第152行是:

fseek(self :: $ dat,$ offset,SEEK_CUR);

自PHP 5.6起,此功能有什么变化吗?

代码:

<?php
/**
 * Items class
 *
 * @package   MyAAC
 * @author    Slawkens <slawkens@gmail.com>
 * @copyright 2017 MyAAC
 * @version   0.0.6
 * @link      http://my-aac.org
 */
defined('MYAAC') or die('Direct access not allowed!');

if ( !function_exists( 'stackId' ) )
{
    function stackId( $count )
    {
        if ( $count >= 50 )
            $stack = 8;
        elseif ( $count >= 25 )
            $stack = 7;
        elseif ( $count >= 10 )
            $stack = 6;
        elseif ( $count >= 5 )
            $stack = 5;
        elseif ( $count >= 4 )
            $stack = 4;
        elseif ( $count >= 3 )
            $stack = 3;
        elseif ( $count >= 2 )
            $stack = 2;
        else
            $stack = 1;

        return $stack;
    }
}

class Items
{
    public static $outputDir = '';
    public static $files = array();

    private static $otb, $dat, $spr;
    private static $lastItem;
    private static $loaded = false;

    public function __destruct()
    {
        if(self::$otb)
            fclose(self::$otb);
        if(self::$dat)
            fclose(self::$dat);
        if(self::$spr)
            fclose(self::$spr);
    }

    public static function generate($id = 100, $count = 1)
    {
        if(!self::$loaded)
            self::load();

        $originalId = $id;
        if($id < 100)
            return false;
            //die('ID cannot be lower than 100.');

        rewind(self::$otb);
        rewind(self::$dat);
        rewind(self::$spr);

        $nostand = false;
        $init = false;
        $originalId = $id;

        // parse info from otb
        while( false !== ( $char = fgetc( self::$otb ) ) )
        {
            $byte = HEX_PREFIX.bin2hex( $char );

            if ( $byte == 0xFE )
                $init = true;
            elseif ( $byte == 0x10 and $init ) {
                extract( unpack( 'x2/Ssid', fread( self::$otb, 4 ) ) );

                if ( $id == $sid ) {
                    if ( HEX_PREFIX.bin2hex( fread( self::$otb, 1 ) ) == 0x11 ) {
                        extract( unpack( 'x2/Sid', fread( self::$otb, 4 ) ) );
                        break;
                    }
                }
                $init = false;
            }
        }

        self::$lastItem = array_sum( unpack( 'x4/S*', fread( self::$dat, 12 )));
        if($id > self::$lastItem)
            return false;

        //ini_set('max_execution_time', 300); 
        // parse info from dat
        for( $i = 100; $i <= $id; $i++ ) {
            while( ( $byte = HEX_PREFIX.bin2hex( fgetc( self::$dat ) ) ) != 0xFF ) {
                $offset = 0;
                switch( $byte ) {
                    case 0x00:
                    case 0x09:
                    case 0x0A:
                    case 0x1A:
                    case 0x1D:
                    case 0x1E:
                        $offset = 2;
                        break;

                    case 0x16:
                    case 0x19:
                        $offset = 4;
                        break;

                    case 0x01:
                    case 0x02:
                    case 0x03:
                    case 0x04:
                    case 0x05:
                    case 0x06:
                    case 0x07:
                    case 0x08:
                    case 0x0B:
                    case 0x0C:
                    case 0x0D:
                    case 0x0E:
                    case 0x0F:
                    case 0x10:
                    case 0x11:
                    case 0x12:
                    case 0x13:
                    case 0x14:
                    case 0x15:
                    case 0x17:
                    case 0x18:
                    case 0x1B:
                    case 0x1C:
                    case 0x1F:
                    case 0x20:
                        break;

                    default:
                        return false; #trigger_error( sprintf( 'Unknown .DAT byte %s (previous byte: %s; address %x)', $byte, $prev, ftell( $dat ), E_USER_ERROR ) );
                        break;
                }

                $prev = $byte;
                fseek( self::$dat, $offset, SEEK_CUR );
            }
            extract( unpack( 'Cwidth/Cheight', fread( self::$dat, 2 ) ) );

            if ( $width > 1 or $height > 1 ) {
                fseek( self::$dat, 1, SEEK_CUR );
                $nostand = true;
            }

            $sprites_c = array_product( unpack( 'C*', fread( self::$dat, 5 ) ) ) * $width * $height;
            $sprites = unpack( 'S*', fread( self::$dat, 2 * $sprites_c ) );
        }

        if ( array_key_exists( stackId( $count ), $sprites ) ) {
            $sprites = (array) $sprites[stackId( $count )];
        }
        else {
            $sprites = (array) $sprites[array_rand( $sprites ) ];
        }

        fseek( self::$spr, 6 );

        $sprite = imagecreatetruecolor( 32 * $width, 32 * $height );
        imagecolortransparent( $sprite, imagecolorallocate( $sprite, 0, 0, 0 ) );

        foreach( $sprites as $key => $value ) {
            fseek( self::$spr, 6 + ( $value - 1 ) * 4 );
            extract( unpack( 'Laddress', fread( self::$spr, 4 ) ) );

            fseek( self::$spr, $address + 3 );
            extract( unpack( 'Ssize', fread( self::$spr, 2 ) ) );

            list( $num, $bit ) = array( 0, 0 );

            while( $bit < $size ) {
                $pixels = unpack( 'Strans/Scolored', fread( self::$spr, 4 ) );
                $num += $pixels['trans'];
                for( $i = 0; $i < $pixels['colored']; $i++ )
                {
                    extract( unpack( 'Cred/Cgreen/Cblue', fread( self::$spr, 3 ) ) );

                    $red = ( $red == 0 ? ( $green == 0 ? ( $blue == 0 ? 1 : $red ) : $red ) : $red );

                    imagesetpixel( $sprite,
                        $num % 32 + ( $key % 2 == 1 ? 32 : 0 ),
                        $num / 32 + ( $key % 4 != 1 and $key % 4 != 0 ? 32 : 0 ),
                        imagecolorallocate( $sprite, $red, $green, $blue ) );

                    $num++;
                }

                $bit += 4 + 3 * $pixels['colored'];
            }
        }

        if ( $count >= 2 ) {
            if ( $count > 100 )
                $count = 100;

            $font = 3;
            $length = imagefontwidth( $font ) * strlen( $count );

            $pos = array(
                'x' => ( 32 * $width ) - ( $length + 1 ),
                'y' => ( 32 * $height ) - 13
            );
            imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
            imagestring( $sprite, $font, $pos['x'], $pos['y'] - 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
            imagestring( $sprite, $font, $pos['x'] - 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) );

            imagestring( $sprite, $font, $pos['x'], $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
            imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'], $count, imagecolorallocate( $sprite, 1, 1, 1 ) );
            imagestring( $sprite, $font, $pos['x'] + 1, $pos['y'] + 1, $count, imagecolorallocate( $sprite, 1, 1, 1 ) );

            imagestring( $sprite, $font, $pos['x'], $pos['y'], $count, imagecolorallocate( $sprite, 219, 219, 219 ) );
        }

        $imagePath = self::$outputDir . ($count > 1 ? $originalId . '-' . $count : $originalId ) . '.gif';

        // save image
        imagegif($sprite, $imagePath);
    }

    public static function load()
    {
        if(!defined( 'HEX_PREFIX'))
            define('HEX_PREFIX', '0x');

        self::$otb = fopen(self::$files['otb'], 'rb');
        self::$dat = fopen(self::$files['dat'], 'rb');
        self::$spr = fopen(self::$files['spr'], 'rb');

        if(!self::$otb || !self::$dat || !self::$spr)
            die('ERROR: Cannot load data files.');
        /*
        if ( $nostand )
        {
            for( $i = 0; $i < sizeof( $sprites ) / 4; $i++ )
            {
                $sprites = array_merge( (array) $sprites, array_reverse( array_slice( $sprites, $i * 4, 4 ) ) );
            }
        }
        else
        {
            $sprites = (array) $sprites[array_rand( $sprites ) ];
        }
        */

        self::$loaded = true;
    }

    public static function loaded() {
        return self::$loaded;
    }
}

1 个答案:

答案 0 :(得分:0)

有可能无限循环。如果您认为循环正常,可能是您尝试在php.ini文件中增加执行时间,如下所示:

max_execution_time = 360      ; Maximum execution time of each script

或者只需将此命令放在脚本的开头:

set_time_limit(0);