📄 common.php
字号:
/** * Get the implemented dependency relations (has, lt, ge etc.) * * @return array * @static */ function getDependencyRelations() { return $GLOBALS['_PEAR_Common_dependency_relations']; } // }}} // {{{ getFileRoles() /** * Get the implemented file roles * * @return array * @static */ function getFileRoles() { return $GLOBALS['_PEAR_Common_file_roles']; } // }}} // {{{ getReplacementTypes() /** * Get the implemented file replacement types in * * @return array * @static */ function getReplacementTypes() { return $GLOBALS['_PEAR_Common_replacement_types']; } // }}} // {{{ getProvideTypes() /** * Get the implemented file replacement types in * * @return array * @static */ function getProvideTypes() { return $GLOBALS['_PEAR_Common_provide_types']; } // }}} // {{{ getScriptPhases() /** * Get the implemented file replacement types in * * @return array * @static */ function getScriptPhases() { return $GLOBALS['_PEAR_Common_script_phases']; } // }}} // {{{ validPackageName() /** * Test whether a string contains a valid package name. * * @param string $name the package name to test * * @return bool * * @access public */ function validPackageName($name) { return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); } // }}} // {{{ validPackageVersion() /** * Test whether a string contains a valid package version. * * @param string $ver the package version to test * * @return bool * * @access public */ function validPackageVersion($ver) { return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); } // }}} // {{{ downloadHttp() /** * Download a file through HTTP. Considers suggested file name in * Content-disposition: header and can run a callback function for * different events. The callback will be called with two * parameters: the callback type, and parameters. The implemented * callback types are: * * 'setup' called at the very beginning, parameter is a UI object * that should be used for all output * 'message' the parameter is a string with an informational message * 'saveas' may be used to save with a different file name, the * parameter is the filename that is about to be used. * If a 'saveas' callback returns a non-empty string, * that file name will be used as the filename instead. * Note that $save_dir will not be affected by this, only * the basename of the file. * 'start' download is starting, parameter is number of bytes * that are expected, or -1 if unknown * 'bytesread' parameter is the number of bytes read so far * 'done' download is complete, parameter is the total number * of bytes read * 'connfailed' if the TCP connection fails, this callback is called * with array(host,port,errno,errmsg) * 'writefailed' if writing to disk fails, this callback is called * with array(destfile,errmsg) * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $url the URL to download * @param object $ui PEAR_Frontend_* instance * @param object $config PEAR_Config instance * @param string $save_dir (optional) directory to save file in * @param mixed $callback (optional) function/method to call for status * updates * * @return string Returns the full path of the downloaded file or a PEAR * error on failure. If the error is caused by * socket-related errors, the error object will * have the fsockopen error code available through * getCode(). * * @access public */ function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) { if ($callback) { call_user_func($callback, 'setup', array(&$ui)); } if (preg_match('!^http://([^/:?#]*)(:(\d+))?(/.*)!', $url, $matches)) { list(,$host,,$port,$path) = $matches; } if (isset($this)) { $config = &$this->config; } else { $config = &PEAR_Config::singleton(); } $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; if ($proxy = parse_url($config->get('http_proxy'))) { $proxy_host = @$proxy['host']; $proxy_port = @$proxy['port']; $proxy_user = @$proxy['user']; $proxy_pass = @$proxy['pass']; if ($proxy_port == '') { $proxy_port = 8080; } if ($callback) { call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); } } if (empty($port)) { $port = 80; } if ($proxy_host != '') { $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); if (!$fp) { if ($callback) { call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, $errno, $errstr)); } return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); } $request = "GET $url HTTP/1.0\r\n"; } else { $fp = @fsockopen($host, $port, $errno, $errstr); if (!$fp) { if ($callback) { call_user_func($callback, 'connfailed', array($host, $port, $errno, $errstr)); } return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); } $request = "GET $path HTTP/1.0\r\n"; } $request .= "Host: $host:$port\r\n". "User-Agent: PHP/".PHP_VERSION."\r\n"; if ($proxy_host != '' && $proxy_user != '') { $request .= 'Proxy-Authorization: Basic ' . base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; } $request .= "\r\n"; fwrite($fp, $request); $headers = array(); while (trim($line = fgets($fp, 1024))) { if (preg_match('/^([^:]+):\s+(.*)\s*$/', $line, $matches)) { $headers[strtolower($matches[1])] = trim($matches[2]); } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { if ($matches[1] != 200) { return PEAR::raiseError("File http://$host:$port$path not valid (received: $line)"); } } } if (isset($headers['content-disposition']) && preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|$)/', $headers['content-disposition'], $matches)) { $save_as = basename($matches[1]); } else { $save_as = basename($url); } if ($callback) { $tmp = call_user_func($callback, 'saveas', $save_as); if ($tmp) { $save_as = $tmp; } } $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; if (!$wp = @fopen($dest_file, 'wb')) { fclose($fp); if ($callback) { call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); } return PEAR::raiseError("could not open $dest_file for writing"); } if (isset($headers['content-length'])) { $length = $headers['content-length']; } else { $length = -1; } $bytes = 0; if ($callback) { call_user_func($callback, 'start', array(basename($dest_file), $length)); } while ($data = @fread($fp, 1024)) { $bytes += strlen($data); if ($callback) { call_user_func($callback, 'bytesread', $bytes); } if (!@fwrite($wp, $data)) { fclose($fp); if ($callback) { call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); } return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); } } fclose($fp); fclose($wp); if ($callback) { call_user_func($callback, 'done', $bytes); } return $dest_file; } // }}} // {{{ sortPkgDeps() /** * Sort a list of arrays of array(downloaded packagefilename) by dependency. * * It also removes duplicate dependencies * @param array * @param boolean Sort packages in reverse order if true * @return array array of array(packagefilename, package.xml contents) */ function sortPkgDeps(&$packages, $uninstall = false) { $ret = array(); if ($uninstall) { foreach($packages as $packageinfo) { $ret[] = array('info' => $packageinfo); } } else { foreach($packages as $packagefile) { if (!is_array($packagefile)) { $ret[] = array('file' => $packagefile, 'info' => $a = $this->infoFromAny($packagefile), 'pkg' => $a['package']); } else { $ret[] = $packagefile; } } } $checkdupes = array(); $newret = array(); foreach($ret as $i => $p) { if (!isset($checkdupes[$p['info']['package']])) { $checkdupes[$p['info']['package']][] = $i; $newret[] = $p; } } $this->_packageSortTree = $this->_getPkgDepTree($newret); $func = $uninstall ? '_sortPkgDepsRev' : '_sortPkgDeps'; usort($newret, array(&$this, $func)); $this->_packageSortTree = null; $packages = $newret; } // }}} // {{{ _sortPkgDeps() /** * Compare two package's package.xml, and sort * so that dependencies are installed first * * This is a crude compare, real dependency checking is done on install. * The only purpose this serves is to make the command-line * order-independent (you can list a dependent package first, and * installation occurs in the order required) * @access private */ function _sortPkgDeps($p1, $p2) { $p1name = $p1['info']['package']; $p2name = $p2['info']['package']; $p1deps = $this->_getPkgDeps($p1); $p2deps = $this->_getPkgDeps($p2); if (!count($p1deps) && !count($p2deps)) { return 0; // order makes no difference } if (!count($p1deps)) { return -1; // package 2 has dependencies, package 1 doesn't } if (!count($p2deps)) { return 1; // package 1 has dependencies, package 2 doesn't } // both have dependencies if (in_array($p1name, $p2deps)) { return -1; // put package 1 first: package 2 depends on package 1 } if (in_array($p2name, $p1deps)) { return 1; // put package 2 first: package 1 depends on package 2 } if ($this->_removedDependency($p1name, $p2name)) { return -1; // put package 1 first: package 2 depends on packages that depend on package 1 } if ($this->_removedDependency($p2name, $p1name)) { return 1; // put package 2 first: package 1 depends on packages that depend on package 2 } // doesn't really matter if neither depends on the other return 0; } // }}} // {{{ _sortPkgDepsRev() /** * Compare two package's package.xml, and sort * so that dependencies are uninstalled last * * This is a crude compare, real dependency checking is done on uninstall. * The only purpose this serves is to make the command-line * order-independent (you can list a dependency first, and * uninstallation occurs in the order required) * @access private */ function _sortPkgDepsRev($p1, $p2) { $p1name = $p1['info']['package']; $p2name = $p2['info']['package']; $p1deps = $this->_getRevP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -