이 글은 주로 Linux에서 PHP가 외부 명령을 구현하는 방법을 소개합니다. 관심 있는 친구들이 참고하면 좋습니다.
디렉토리:
1. PHP에서 외부 명령 호출 소개
2. 보안 문제
3. 시간 초과 문제
4. PHP가 Linux 환경에서 명령을 실행할 때 발생하는 문제
1, PHP에서 외부 명령 호출 소개
PHP에서 외부 명령을 호출하려면 1> 특수 함수 호출, 2> 백틱, 3>popen() 함수를 사용하여 프로세스를 엽니다. 달성 방법:
방법 1: PHP에서 제공하는 특수 함수 사용(4개):
PHP는 외부 명령 실행을 위한 4가지 특수 함수를 제공합니다: exec(), system(), passthru(), shell_exec( )
1) exec()
Prototype: string exec ( string $command [, array &$output [, int &$return_var ] )
설명: exec는 시스템 실행 시 결과를 출력하지 않습니다. 외부 명령이지만 결과의 마지막 행을 반환합니다. 결과를 얻으려면 두 번째 매개변수를 사용하여 지정된 배열로 출력하면 됩니다. 이 배열의 한 레코드는 출력 행을 나타냅니다. 즉, 출력 결과가 20줄이면 이 배열에는 20개의 레코드가 있게 됩니다. 따라서 다른 시스템 외부 명령을 호출한 결과를 반복적으로 출력해야 하는 경우 출력 시 배열 unset($output)을 지우는 것이 가장 좋습니다. 혼동을 방지하기 위해 각 시스템 외부 명령의 결과를 확인합니다. 세 번째 매개변수는 명령 실행 상태 코드를 가져오는 데 사용됩니다. 일반적으로 실행이 성공하면 0이 반환됩니다.
<?php exec("dir",$output); print_r($output); ?>
2) system()
Prototype: string system ( string $command [, int &$return_var ] )
설명: system과 exec의 차이점은 시스템이 외부에 있다는 것입니다. 실행 시스템 명령을 내리면 주어진 명령을 실행하고 그 결과를 출력하고 반환한다. 두 번째 매개변수는 선택사항이며 명령이 실행된 후 상태 코드를 가져오는 데 사용됩니다.
<?php system("pwd",$result); print $result;//输出命令的结果状态码 ?>
두 번째 매개변수 결과 상태 코드에 대한 간략한 소개:
0이 반환되면 작업이 성공한 것이고,
Bash에서는 치명적인 신호에 오류가 발생하면 bash는 128을 반환합니다. +신호 번호를 반환 값으로 사용합니다.
명령어를 찾을 수 없으면 127이 반환됩니다.
명령을 찾았지만 명령을 실행할 수 없는 경우 126이 반환됩니다.
또한 Bash 자체는 마지막 명령의 반환 값을 반환합니다.
실행 중 오류가 발생하면 0이 아닌 값이 반환됩니다.
치명적 신호 : 128 + signo
명령을 찾을 수 없음 : 127
실행할 수 없음 : 126
쉘 스크립트가 성공적으로 실행됨 : 마지막 명령 종료 상태를 반환
실행 중 치명적 : 0이 아닌 값을 반환
3) passthru()
Prototype: void passthru ( string $command [, int &$return_var ] )
설명: passthru와 시스템의 차이점, passthru는 어떤 값도 반환하지 않고 결과를 브라우저에 직접 출력합니다. , 이미지 데이터와 같은 이진 데이터를 출력할 수 있습니다. 두 번째 매개변수는 선택사항이며 상태 코드입니다.
<?php header("Content-type:image/gif"); passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm"); ?>
4) shell_exec()
프로토타입: string shell_exec ( string $cmd )
설명: $cmd
<?php $output = shell_exec('ls -lart'); echo "<pre class="brush:php;toolbar:false">$output"; ?>
명령을 직접 실행하세요. 방법 2: 역방향 skimming No.
프로토타입: 시스템 외부 명령을 실행하기 위한 백틱 `(같은 키에 ~ 사용)
설명: 이 방법을 사용하여 시스템 외부 명령을 실행하는 경우 shell_exec 기능을 사용할 수 있는지 확인하고, 그렇지 않으면 이 방법을 사용하세요. 백틱은 시스템 외부 명령을 실행하는 데 사용할 수 없습니다.
<?php echo `dir`; ?>
방법 3: popen() 함수를 사용하여 프로세스
프로토타입: 리소스 popen( 문자열 $command , 문자열 $mode )
설명: 명령과 상호 작용할 수 있습니다. 이전에 소개한 방법은 단순히 명령을 실행할 수만 있을 뿐 명령과 상호 작용할 수는 없습니다. 예를 들어, 시스템 사용자를 추가할 때 su를 호출하여 현재 사용자를 루트 사용자로 변경해야 하는 경우가 있습니다. su 명령은 명령줄에 루트 암호를 입력해야 합니다. 이 경우 앞에서 언급한 방법을 사용하는 것은 당연히 불가능합니다.
popen() 함수는 프로세스 파이프를 열어 주어진 명령을 실행하고 읽고 쓸 수 있는 파일 핸들을 반환합니다. 반환 값은 파일 포인터를 반환하는 fopen() 함수와 동일합니다. 열기(읽기 또는 쓰기)에 단일 모드를 사용하지 않는 한 pclose() 함수를 사용하여 닫아야 합니다. 이 포인터는 fgets(), fgetss(), fwrite()에 의해 호출될 수 있습니다. 오류가 발생하면 FALSE를 반환합니다.
<?php error_reporting(E_ALL); /* Add redirection so we can get stderr. */ $handle = popen('/path/to/executable 2>&1', 'r'); echo "'$handle'; " . gettype($handle) . "\n"; $read = fread($handle, 2096); echo $read; pclose($handle); ?>
2. 보안 관련 사항:
WEB 프로그램 개발에는 기본적으로 PHP가 사용되기 때문에 보안은 사람들이 중요하게 생각하는 부분이 되었습니다.
그래서 PHP 설계자는 PHP에 안전 모드라는 문을 추가했습니다.
php.ini에서 safe_mode = On으로 설정
如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:
执行外部命令
在打开文件时有些限制
连接MySQL数据库
基于HTTP的认证
在安全模式下,只有在特定目录中的外部程序才可以被执行,对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令,或在编译PHP 是加上–with-exec-dir选项来指定,默认是/usr/local/php/bin。
当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。
三、关于超时问题
当执行命令的返回结果非常庞大时,可以需要考虑将返回结果输出至其他文件,再另行读取文件,这样可以显著提高程序执行的效率。
如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是在等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中,如:
<?php system("/usr/local/bin/order_proc > /tmp/abc "); ?>
但我调用的DOS命令需要几分钟的时间,而且为了批处理不能简单的把结果写入文件了事,要顺序执行以下的程序
PHP设置了调用系统命令的时间限制,如果调用命令超时,虽然这个命令还是会被执行完,但PHP没有得到返回值,被终止了(最可恨的是,不显示任何错误)
修改php.ini并重启Apache以允许系统命令运行更长的时间
max_execution_time = 600
四、关于PHP运行linux环境中命令出现的问题
php一般是以apache用户身份去执行的,也可能是www用户,把apache加入到存储你文件的父文件夹属组里去,然后改该父文件夹权限为775,这样属组成员就有写的权限,而apache属于这个组就可以改写该目录下所有文件的权限。
例如:chown www:www dirName
这样dirName目录才能被php所控制
注意:改apache/php的运行用户方法不安全
另外即使文件或目录已经是www,php的安全设置也都照顾到,一些自己安装linux的命令仍然可能无法运行,例如我曾经安装的ffmpeg软件,原因就是linux的运行权限问题,即使ffmpeg有www权限设置,但由于ffmpeg所依赖的库文件是不允许www用户运行,所以php运行此程序仍然会报127或126错误,通过 ldd 命令可以查看ffmpeg命令依赖的库情况。
这个时候就必须对ffmpeg的依赖库经行设置。具体方法属于linux管理中的话题,这里不就讨论了。
以上就是本文的全部内容,希望对大家的学习有所帮助。
相关推荐:
위 내용은 Linux에서 외부 명령을 실행하는 PHP 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!