0

我有一个在 ubuntu 中完美运行的脚本,最近我将完全相同的脚本复制到 centos6 服务器,但出现以下错误:

PHP Warning:  array_map(): Argument #2 should be an array in /copy_scripts/classes/Vserver.class.php on line 245

编码

/**
 * Get an array of open files
 * @param array $aExt
 * @return array of arrays ['views','size','path']
 */
public function getOpenFiles($aExt=array()) {
        $aOpenFiles = self::GetList(self::$sLogOpenFiles);
        $aOpenFiles = array_map( create_function('$v', '
                        $v = trim($v);
                        $aFile = preg_split("#[\t\s]+#",$v);
                        $oFile = new VserverFile($aFile[2]);
                        $oFile->setViews($aFile[0]);
                        return $oFile;'),
                $aOpenFiles
        );
        //echo "<pre>";
        //print_r($aOpenFiles);
        return  $aOpenFiles;
}

可能是php版本之间的区别吗?

分:

PHP 5.3.3 (cli) (built: Jul  3 2012 16:53:21)

ubuntu

PHP 5.3.10-2 (cli) (built: Feb 20 2012 19:39:00)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

到目前为止我已经尝试过:

  • 更改 php.ini 中的设置重新启动 php。

完整代码:

<?php
/**
 * 
 * Global Video Server class
 * Singleton class
 * Has methods to manipulate files
 * @author kpoxas
 *
 */
class Vserver {
    static protected $oInstance=null;
    static protected $iTimeStart, $iTimeEnd;
    const FILE_NOEXIST  = -2;
    const FILE_ZEROSIZE = -4;
    const FILE_DIFF     = -8;   
    /*
     * Path /var/www/HDD_PATH/
     */
    static public $sHDDPath = null;
    /*
     * Path /var/www/SSD_PATH/
     */
    static public $sSSDPath = null;
    /*
     *  Folder same on every RAID.../FOLDER/...
     */
    static public $sHTTPFolder = null;
    /*
     * Open Files Log
     */
    static public $sLogOpenFiles = null;
    /*
     * Limit of Free space on SSD in percents
     */
    static public $iSSDUsage = 90;
    /*
     * Limit of Free space on SSD in percents (not delete below)
     */ 
    static public $iSSDDeleteUsage = 80;
    /*
     * Limit of Free space on SSD in bytes (not delete below)
     */ 
    static public $iSSDDeleteUsageAbsolute = 5368709120;
    /*
     * Min views count of file to copy
     */
    static public $iMinViews = 2;   
    /*
     * Search within files older than $iDaysToDelete days 
     */
    static public $iDaysToDelete = 1;
    /*
     * Test Mode
     * File manipulations aren't executed
     * Only log mode
     */
    static public $bTest = false;
    /*
     * Store openfiles.txt log  
     */
    static protected $sOpenFiles = null;
    /**
     * Äåñêðèïòîð áëîêèðóþùåãî ôàéëà
     *
     * @var string
     */
    protected $oLockFile=null;      
    /**
     * Singleton Object implementation
     *
     * @return VSERVER
     */
    static public function getInstance() {
        if (isset(self::$oInstance) and (self::$oInstance instanceof self)) {
            return self::$oInstance;
        } else {
            self::$oInstance= new self();
            return self::$oInstance;
        }
    }
    /**
     * Get Log content
     * @param string $sLogPath
     * @return string 
     */
    static public function GetLog($sLogPath) {
        if ($s = @file_get_contents($sLogPath)) {
            $s = trim($s);
            if (!empty($s)) {
                return $s;
            }
        }
        return false;
    }
    /**
     * Get Log content in list mode divided by EOL
     * @param string $sLogPath
     * @return array
     */
    static public function GetList($sLogPath) {
        if ($sList = self::GetLog($sLogPath)) {         
            return explode(PHP_EOL,trim($sList));
        }
    }
    /**
     * Check if directory exists and chmod 775
     * @param $directory
     */
    static public function CheckDirectory($directory) {         
        $directory = rtrim($directory, '/\\');
        if (is_dir($directory)) @chmod($directory, 0775);
        else {
            if (!mkdir($directory, 0755, true)) {
                //self::AddError ('Directory does not exist', $directory);
                return false;
            }
        }       
    }
    /**
     * Check if file exist
     * Check if file has zero size      
     * @param string $filename
     */
    static public function CheckFile($filename) {       
        if (file_exists($filename) && !is_file($filename)) {
            self::log("NO VALID FILEPATH: {$filename}");
            return false;
        } else if(!file_exists($filename)) {
            self::log("FILE DOESN'T EXIST: {$filename}");
            return self::FILE_NOEXIST;          
        } else if(!filesize($filename)) {
            self::log("FILE ZEROSIZE: {$filename}");
            return self::FILE_ZEROSIZE;
        } 
        else return true;
    }
    /**
     * Check if file1 is identical to file2
     * @param string $filename1
     * @param string $filename2
     */
    static public function CheckIdentity($filename1, $filename2) {      
        if (self::CheckFile($filename1)>0 && self::CheckFile($filename2)>0) {
            if (filesize($filename1)===filesize($filename2)) {
                self::log("FILES: {$filename1} AND {$filename2} ARE IDENTICAL");
                return true;
            }
            self::log("FILES: {$filename1} AND {$filename2} ARE DIFFERENT");
            return false;
        }       
    }
    /**
     * Copy file from $source to $dest
     * Make www-data owner
     * Make perms 755
     */
    static public function Copy($source, $dest = null) {
        self::log("COPY {$source} TO {$dest}"); 

        if (self::$bTest) return true;

        self::CheckDirectory(dirname($dest));
        // copy
        $sCmd = "cp -f '{$source}' '{$dest}'";
        self::exec($sCmd);
        // chown        
        $sCmdChown = "chown www-data:www-data '{$dest}'";
        self::exec($sCmdChown);
        // chmod
        $sCmdChmod = "chmod 775 '{$dest}'";
        self::exec($sCmdChmod);
        return true;
    }
    /**
     * Delete file  
     */
    static public function Delete($source) {
        self::log("DELETE {$source}");  
        if (self::$bTest) return true;
        // chmod
        $sCmdChmod = "rm '{$source}'";
        self::exec($sCmdChmod);
    }
    /** 
     * Get free space of catalog or storage in bytes
     * @param string $sDir
     */
    static public function GetFreeSpace($sDir = '') {
        return disk_free_space($sDir);
    }
    /** 
     * Get total space of catalog or storage in bytes
     * @param string $sDir
     */
    static public function GetTotalSpace($sDir = '') {
        return disk_total_space($sDir);
    }
    /** 
     * Get used space of catalog or storage in percents
     * @param string $sDir
     */
    static public function GetUsage($sDir = '') {
        //$sCmd = "df -k {$sDir} | grep -Eo '[0-9]+%'";
        //return intval(self::exec($sCmd));
        return round(1-self::GetFreeSpace($sDir)/self::GetTotalSpace($sDir),4)*100;
    }
    /**
     * Exec command wrapper 
     */
    static public function exec($sCmd = null, &$aVar=null) {
        if (empty($sCmd)) {
            return;
        }       
        self::log($sCmd);
        return exec($sCmd, $aVar);
    }

    static public function log($sStr) {
        echo "{$sStr}<br>\n";   
    }
    /**
     * Get open files log    
     * @return string
     */
    static public function getOpenFilesContent() {      
        if (self::$sOpenFiles === null) {
            self::$sOpenFiles = self::GetLog(self::$sLogOpenFiles);
        }
        return self::$sOpenFiles;
    }
    /**
     * Get an array of open files
     * @param array $aExt
     * @return array of arrays ['views','size','path']
     */
    public function getOpenFiles($aExt=array()) {       
        $aOpenFiles = self::GetList(self::$sLogOpenFiles);
        $aOpenFiles = array_map( create_function('$v', ' 
                $v = trim($v);
                $aFile = preg_split("#[\t\s]+#",$v);
                $oFile = new VserverFile($aFile[2]);
                $oFile->setViews($aFile[0]);                
                return $oFile;'),
            $aOpenFiles
        );
        //echo "<pre>";
        //print_r($aOpenFiles);
        return  $aOpenFiles;
    }

    public function getFileList($sDir=null, $aExt=array('flv','mp4'), $sGrep='') {
        if (!$sDir || empty($aExt)) return;
        $aCmdExt = "\( -name '*."
            .implode("' -o -name '*.",$aExt)
            ."' \)";
        $sCmd = "find {$sDir} {$aCmdExt} -mmin +".self::$iDaysToDelete."";
        // sort by date
        //$sCmd = "find {$sDir} {$aCmdExt} -printf '%T@ %p\n'| sort -k 1n | cut -d' ' -f2-";
        if (!empty($sGrep)) {
            $sCmd.= " | {$sGrep}";
        }
        self::exec($sCmd,$aFiles);  
        return $aFiles;             
    }
    /**
     * 
     * Get list of storages
     */
    public function getStorages() {     
        $sCmd = "df -k | grep -Eo 'storage[0-9]+$'";        
        self::exec($sCmd,$aStorages);       
        return $aStorages;              
    }
    /**
     * 
     * Get list of megastorages
     */
    public function getMegaStorages() {     
        $sCmd = "df -k | sort -k5 -r | grep -Eo 'megastorage[0-9]+$'";      
        self::exec($sCmd,$aStorages);       
        return $aStorages;              
    }
    /**
     * Copy opened files to SSD 
     */
    public function copyToSSD() {       
        $this->setLock(__FUNCTION__.'.lock');           
        if($this->isLock()) {
            self::log("Process has already started.");
            return;
        } 

        $iCopied    = 0;
        $iIgnored   = 0;
        $aOpenedFiles = $this->GetOpenFiles();
        foreach ($aOpenedFiles as $oFile) {
            if (self::GetUsage(self::$sSSDPath) < self::$iSSDUsage) {
                if ($oFile->getViews() >=self::$iMinViews && $oFile->synchronize()) $iCopied++;
                else $iIgnored++;
            } else {
                break;
            }
        }
        self::log("COPIED: {$iCopied}");
        self::log("IGNORED: {$iIgnored}");
        self::log("SSD USAGE: ".self::GetUsage(self::$sSSDPath)."%");
    }
    /**
     * DELETE FROM SSD  
     */
    public function deleteFromSSD() {

        $this->setLock(__FUNCTION__.'.lock');           
        if($this->isLock()) {
            self::log("Process has already started.");
            return;
        } 

        $iDeleted   = 0;
        $iIgnored   = 0;
        /*
         * Get megastorages sorted by usage desc, 
         */
        $aMegaStorages = $this->getMegaStorages();              
        foreach ($aMegaStorages as &$sMegaStorage) {
            /*
             * Get files in current megastorage 
             */
            $aFileList  = $this->getFileList('/'.$sMegaStorage);            
            if (empty($aFileList)) {
                self::log("NO FILES FOUND in {$sMegaStorage}");
                continue;
            }
            $aFileList = array_map(
                create_function('$v', '             
                    $oFile = new VserverFile(trim($v));                             
                    return $oFile;          
                '),
                $aFileList
            );  
            /*
             * Delete files until appropriate usage
             */ 
            $iFreeSpace     = self::GetFreeSpace('/'.$sMegaStorage);
            $iTotalSpace    = self::GetTotalSpace('/'.$sMegaStorage);           
            foreach ($aFileList as &$oFile) {
                $iUsageCurrent = round(1-$iFreeSpace/$iTotalSpace,4)*100;
                self::Log($sMegaStorage." ".$iUsageCurrent."%");                    
                if ($iUsageCurrent > self::$iSSDDeleteUsage) {  
                    if (!$oFile->isOpened()) {
                        $iFreeSpace += $oFile->getSize();
                        $oFile->synchronize();
                        $oFile->deleteFromSSD();
                        $iDeleted++;    
                    } else $iIgnored++;
                } else {
                    break;
                }
            }
        }
        /*
        $aFileList  = $this->getFileList(self::$sSSDPath);
        if (empty($aFileList)) {
            self::log("NO FILES FOUND");
            return;
        }
        $aFileList = array_map(
            create_function('$v', '             
                $oFile = new VserverFile(trim($v));                             
                return $oFile;          
            '),
            $aFileList
        );          

        foreach ($aFileList as $oFile) {
            if (self::GetUsage(self::$sSSDPath) > self::$iSSDDeleteUsage) { 
                if (!$oFile->isOpened()) {
                    $oFile->synchronize();
                    $oFile->deleteFromSSD();
                    $iDeleted++;
                } else $iIgnored++;
            } else {
                break;
            }
        }
        */
        self::log("DELETED: {$iDeleted}");
        self::log("IGNORED: {$iIgnored}");
        self::log("SSD USAGE: ".self::GetUsage(self::$sSSDPath)."%");
    }
    /**
     * DELETE FROM SSD
     * USING ABSOLUTE VALUE of $iSSDDeleteUsageAbsolute
     */
    public function deleteFromSSDAbsolute() {

        $this->setLock(__FUNCTION__.'.lock');           
        if($this->isLock()) {
            self::log("Process has already started.");
            return;
        } 

        $iDeleted   = 0;
        $iIgnored   = 0;
        /*
         * Get megastorages sorted by usage desc, 
         */
        $aMegaStorages = $this->getMegaStorages();              
        foreach ($aMegaStorages as &$sMegaStorage) {
            /*
             * Get files in current megastorage 
             */
            $aFileList  = $this->getFileList('/'.$sMegaStorage);            
            if (empty($aFileList)) {
                self::log("NO FILES FOUND in {$sMegaStorage}");
                continue;
            }
            $aFileList = array_map(
                create_function('$v', '             
                    $oFile = new VserverFile(trim($v));                             
                    return $oFile;          
                '),
                $aFileList
            );  
            /*
             * Delete files until appropriate usage
             */ 
            $iFreeSpace     = self::GetFreeSpace('/'.$sMegaStorage);            
            foreach ($aFileList as &$oFile) {               
                self::Log($sMegaStorage." ".(round($iFreeSpace/1024/1024/1024,2))." G");                    
                if ($iFreeSpace < self::$iSSDDeleteUsageAbsolute) { 
                    if (!$oFile->isOpened()) {
                        $iFreeSpace += $oFile->getSize();
                        $oFile->synchronize();
                        $oFile->deleteFromSSD();
                        $iDeleted++;    
                    } else $iIgnored++;
                } else {
                    break;
                }
            }
        }

        self::log("DELETED: {$iDeleted}");
        self::log("IGNORED: {$iIgnored}");
        self::log("FREE SPACE: ".(round($iFreeSpace/1024/1024/1024,2))." G");       
    }
    /**
     * 
     * Get Identical files on storages 
     */
    public function getIdentical() {
        $this->setLock(__FUNCTION__.'.lock');           
        if($this->isLock()) {
            self::log("Process has already started.");
            return;
        } 

        $aStorages = $this->getStorages();
        foreach ($aStorages as &$sStorage) {
            $sDir = "/{$sStorage}/".self::$sHTTPFolder;
            $aList[$sStorage] = $this->getFileList($sDir,array('flv'), "grep -Eo '".self::$sHTTPFolder.".*$'");
        }
        $iStorages = sizeof($aList);
        for ($i=0; $i<$iStorages; $i++) {
            reset($aList);
            $sPrimaryStorage = key($aList);
            $aPrimaryFiles = array_shift($aList);
            foreach($aList as $sSecondaryStorage=>&$aSecondaryFiles) {  
                self::log("{$sPrimaryStorage} <-- {$sSecondaryStorage}");
                //array of identical files
                $aIdentical = array_intersect($aPrimaryFiles, $aSecondaryFiles);
                if (!empty($aIdentical)) {
                    // get sizes
                    foreach ($aIdentical as $sFile) {
                        $iPrimaryPath = "/{$sPrimaryStorage}/".$sFile;
                        $iPrimarySize = filesize($iPrimaryPath);
                        $iSecondaryPath = "/{$sSecondaryStorage}/".$sFile;
                        $iSecondarySize = filesize($iSecondaryPath);

                        self::log("| {$iPrimaryPath} <-- {$iPrimarySize}");
                        self::log("| {$iSecondaryPath} <-- {$iSecondarySize}");
                        // delete if sizes are identical
                        if ($iPrimarySize == $iSecondarySize) self::Delete($iSecondaryPath);
                        // if any have null size
                        else if ($iPrimarySize * $iSecondarySize) continue;
                        else if (filectime($iPrimarySize)>filectime($iSecondaryPath))   self::Delete($iSecondaryPath);
                        else if (filectime($iSecondaryPath)>filectime($iPrimarySize))   self::Delete($iPrimarySize);        
                    }                   
                }
            }
        }
        //echo "<pre>";
        //print_r(array_intersect($aPrimaryFiles, $aSecondaryFiles));
        //echo "</pre>";

    }   

    /**
     * Ñîçäàåò áëîêèðîâêó íà ïðîöåññ
     */
    public function setLock($sLockFile=null) {      
        if(!empty($sLockFile)) {
            $this->oLockFile=fopen($sLockFile,'a');
        }
    }
    /**
     * Ïðîâåðÿåò óíèêàëüíîñòü ñîçäàâàåìîãî ïðîöåññà
     */
    public function isLock() {      
        return ($this->oLockFile && !flock($this->oLockFile, LOCK_EX|LOCK_NB));
    }
    /**
     * Ñíèìàåò áëîêèðîâêó íà ïîâòîðíûé ïðîöåññ
     */
    public function unsetLock() {
        return ($this->oLockFile && @flock($this->oLockFile, LOCK_UN));
    }

    public function __construct() {
        self::$iTimeStart = microtime(true); 
    }

    public function __destruct() {
        self::$iTimeEnd = microtime(true);
        $iTimeExecution = round(self::$iTimeEnd - self::$iTimeStart,3);
        $iUsageMem = memory_get_usage(true)/1024/1024;      //Mb
        $iUsageMemPeak = memory_get_peak_usage(true)/1024/1024;     //Mb
        self::log("Execution time: {$iTimeExecution} s");
        self::log("Memory Usage: {$iUsageMem} Mb");
        self::log("Memory Peak Usage: {$iUsageMemPeak} Mb");
        $this->unsetLock();
    }

    /**
     * Class autoloader
     *
     * @param unknown_type $sClassName
     */
    public static function autoload($sClassName) {
        require_once("{$sClassName}.class.php");
    }
}
spl_autoload_register(array('Vserver','autoload'));
?>
4

1 回答 1

2

由于array_map抱怨$aOpenFiles不是一个数组,你可能想看看那个变量。

public function getOpenFiles($aExt=array()) {
  $aOpenFiles = self::GetList(self::$sLogOpenFiles);
  if ( !is_array($aOpenFiles) ) {
    var_dump($aOpenFiles);
    die('not an array');
  }
  $aOpenFiles = array_map( ...

引用:

static public function GetList($sLogPath) {
  if ($sList = self::GetLog($sLogPath)) {         
    return explode(PHP_EOL,trim($sList));
  }
}

...如果$sList计算结果为 false (这很可能发生,因为GetLog在某些情况下返回 false )此函数返回nothing
您必须在某处检查该情况。哪里取决于您希望脚本对什么条件做出反应。例如

static public function GetList($sLogPath) {
  if ($sList = self::GetLog($sLogPath)) {         
    return explode(PHP_EOL,trim($sList));
  }
  return array();
}

会“修复”错误,但如果可行是另一个问题;它可能只会“隐藏”一个症状 - 而不是根本问题。必须有日志文件吗?必须GetList(GetLog())返回一个(非空)数组?等等等等....

于 2012-10-29T08:53:10.407 回答