标签: k2f

在PHP中正确执行shell

问题

我正在使用一个proc_open()用来调用shell命令的函数.看起来我在做STDIO的方式是错误的,有时导致PHP或目标命令锁定.这是原始代码:

function execute($cmd, $stdin=null){
    $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
    fwrite($pipes[0],$stdin);                fclose($pipes[0]);
    $stdout=stream_get_contents($pipes[1]);  fclose($pipes[1]);
    $stderr=stream_get_contents($pipes[2]);  fclose($pipes[2]);
    return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>proc_close($proc) );
}
Run Code Online (Sandbox Code Playgroud)

大部分时间都有效,但这还不够,我想让它始终有效.

stream_get_contents()如果STDIO缓冲区超过4k的数据,则问题在于锁定.

测试用例

function out($data){
    file_put_contents('php://stdout',$data);
}
function err($data){
    file_put_contents('php://stderr',$data);
}
if(isset($argc)){
    // RUN CLI TESTCASE
    out(str_repeat('o',1030);
    err(str_repeat('e',1030);
    out(str_repeat('O',1030);
    err(str_repeat('E',1030);
    die(128); // to test return error code
}else{
    // RUN EXECUTION TEST CASE
    $res=execute('php -f '.escapeshellarg(__FILE__));
}
Run Code Online (Sandbox Code Playgroud)

我们输出一个字符串两次到STDERR和STDOUT,总长度为4120字节(超过4k).这会导致PHP双方都锁定.

显然,stream_select()是要走的路.我有以下代码:

function execute($cmd,$stdin=null,$timeout=20000){
    $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
    $write  = array($pipes[0]);
    $read   = array($pipes[1], $pipes[2]);
    $except = null;
    $stdout …
Run Code Online (Sandbox Code Playgroud)

php proc-open k2f

9
推荐指数
1
解决办法
9523
查看次数

PHP proc_open多次打开

我有一个实用程序函数用于通过CLI(cmd,bash等)执行程序.它返回的3项的数组:STDOUT,STDERREXIT CODE.

到目前为止,它一直很好地没有问题.事实上,我遇到的问题并没有真正阻碍它的功能,但我关注的是性能.

问题是在某些情况下,PHP会多次运行相同的命令(在我的情况下是3次),即使它只应该执行一次.

/**
 * Executes a program and waits for it to finish, taking pipes into account.
 * @param string $cmd Command line to execute, including any arguments.
 * @param string $input Data for standard input.
 * @param boolean $log Whether to log execution failures or not (defaults to true).
 * @return array Array of "stdout", "stderr" and "return".
 */
public static function execute($cmd,$stdin=null,$log=true){
    //static $once=true; if(!$once)die; $once=false;
    $proc=proc_open($cmd, array(
        0=>array('pipe','r'),
        1=>array('pipe','w'), …
Run Code Online (Sandbox Code Playgroud)

php windows proc-open command-line-interface k2f

8
推荐指数
1
解决办法
1369
查看次数

PHP奇怪的DOCUMENT_ROOT

基本上,我正在编写一个框架,作为其功能的一部分,它应该为最终开发人员提供一组完善的URI /路径.

这些路径中的两个使用$_SERVER['DOCUMENT_ROOT']:

/**
 * Absolute filesystem path to web root install (aka docroot).
 * @example "C:/wamp/www" OR "/home/visitgoz/public_html/"
 */
CFG::set('ABS_WWW',
    str_replace(
        $tmpseps,
        DIRECTORY_SEPARATOR,
        truepath($_SERVER['DOCUMENT_ROOT']).'/'
    )
);

/**
 * K2F path relative to web root.
 * @example /K2F/
 */
CFG::set('REL_K2F',
    str_replace(
        array('//','\\'),
        '/',
        str_replace(CFG::get('ABS_WWW'),'/',CFG::get('ABS_K2F'))
    )
);
Run Code Online (Sandbox Code Playgroud)

该代码已经过微调,可以在Linux和Windows上运行.显然,它大部分时间都在Linux上运行,实际上在VPS上非常无缝.

但是,最近,我在HG转销商帐户(共享托管)上试了一下,这一切都破了.我在有问题的机器上打印出$ _SERVER中的数据:

Array
(
**  [DOCUMENT_ROOT] => /usr/local/apache/htdocs
    [GATEWAY_INTERFACE] => CGI/1.1
    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9;q=0.8
    [HTTP_ACCEPT_CHARSET] => ISO-8859-1,utf-8;q=0.7,*;q=0.7
    [HTTP_ACCEPT_ENCODING] => gzip,deflate
    [HTTP_ACCEPT_LANGUAGE] => en-gb,en;q=0.5
    [HTTP_CONNECTION] => keep-alive
    [HTTP_COOKIE] …
Run Code Online (Sandbox Code Playgroud)

php shared-hosting document-root k2f

4
推荐指数
1
解决办法
2161
查看次数