# CURL與PHP-CLI的應用【CLI篇】
標簽(空格分隔): Linux PHP
---
## CLI的普通應用
### 什么是PHP-CLI
php-cli是``php Command Line Interface``的簡稱,即PHP命令行接口,在windows和linux下都是支持PHP-CLI模式的;
### 為什么要使用PHP-CLI
+ 多線程應用
+ 定時執行php程序
+ 開發桌面程序 (使用PHP-CLI和GTK包即可開發桌面,但沒人會用PHP來編寫桌面程序的)
+ 編寫PHP的shell腳本
### 判斷PHP運行模式
PHP的運行模式遠遠不止apache和cli,還包括:**olserver, apache, apache2filter, apache2handler, caudium, cgi (until PHP 5.3), cgi-fcgi, cli, continuity, embed, isapi, litespeed, milter, nsapi, phttpd, pi3web, roxen, thttpd, tux, and webjames.**
```sp
echo php_sapi_name(); //如果是CLI模式下訪問就輸出CLI,如果是Apache就是apache2handler...
```
### PHP-CLI 內置參數
```shell
D:\wamp\bin\php\php5.3.8>php -help
Usage: php [options] [-f] <file> [--] [args...]
php [options] -r <code> [--] [args...]
php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
php [options] -- [args...]
php [options] -a
-a Run interactively
-c <path>|<file> Look for php.ini file in this directory
-n No php.ini file will be used
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-f <file> Parse and execute <file>.
-h This help
-i PHP information
-l Syntax check only (lint)
-m Show compiled in modules
-r <code> Run PHP <code> without using script tags <?..?>
-B <begin_code> Run PHP <begin_code> before processing input lines
-R <code> Run PHP <code> for every input line
-F <file> Parse and execute <file> for every input line
-E <end_code> Run PHP <end_code> after processing all input lines
-H Hide any passed arguments from external tools.
-s Output HTML syntax highlighted source.
-v Version number
-w Output source with stripped comments and whitespace.
-z <file> Load Zend extension <file>.
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin
--ini Show configuration file names
--rf <name> Show information about function <name>.
--rc <name> Show information about class <name>.
--re <name> Show information about extension <name>.
--ri <name> Show configuration for extension <name>.
```
+ 運行指定的php文件:
```sp
<?php
echo 'this is php-cli'
?>
```
```shell
# php /var/www/html/test.php
this is a php-cli
[root@semple html]# php -f 'test.php'
this is a php-cli
```
+ 在命令行直接運行 PHP 代碼
```shell
D:\wamp\bin\php\php5.3.8>php -r "echo 'hello world';"
hello world
```
> 注意: 在運行這些php代碼時沒有開始和結束的標記符!加上 ``-r`` 參數后,這些標記符是不需要的,加上它們會導致語法錯誤。
+ 通過標準輸入(stdin)提供需要運行的 PHP 代碼
```php
// ask for input
fwrite(STDOUT, "Enter your name: ");
// get input
$name = trim(fgets(STDIN));
// write input back
fwrite(STDOUT, "Hello, $name!");
```
```shell
D:\wamp\www>php test.php
Enter your name:
D:\wamp\www>php test.php
Enter your name: zhouzhou
Hello, zhouzhou!
```
### 獲取自定義參數
```php
print_r($argv); //獲取具體的參數;
print_r($argc); //獲取參數的數目;
```
```shell
D:\wamp\www>php test.php #本身執行的php文件就作為一個參數;
Array
(
[0] => test.php
)
1
D:\wamp\www>php test.php arg1 arg2 arg3 arg4
Array
(
[0] => test.php
[1] => arg1
[2] => arg2
[3] => arg3
[4] => arg4
)
5
```
> ``argv``和``argc``也分別可以在$_SERVER數組中得到
```sp
<?php
$args = getopt('g:m:a:'); //只能是單個單詞,如果不是單個單詞就會出錯;
print_r($args);
?>
```
```shell
D:\wamp\www>php test.php -g group -m module -a age
Array
(
[g] => group
[m] => module
[a] => age
)
```
## PHP-CLI在框架中的應用
首先要清楚,大多數PHP-CLI都是在crontab中應用,俗稱'跑腳本'。既然是'跑',那肯定是一個龐大的IO開銷,這個時候放在框架環境中來跑這個腳本的話,至少我的使用過程中遇見過'內存泄漏',php這種語言基本上不會遇見的情況就是在這種情況下遇見的;
+ 在CI框架中應用
```shell
# php /var/www/html/web2/index.php welcome test 這個是在ci里面執行的welcome控制器里面的test方法,后面的以此類推;
```
還可以代入變量
```sp
<?php
class Tools extends CI_Controller {
public function message($to = 'World')
{
echo "Hello {$to}!".PHP_EOL;
}
}
?>
```
```shell
$ cd /path/to/project;
$ php index.php tools message
# Hello John Smith!。
```
+ 在TP框架中的應用
在thinkphp中對CLI的支持并非很好,但我們可以通過``$argv``在框架運行之初就自動組成相應的g,m,a等get變量;甚至另開其一個只能是cli模式訪問文件
```php
//如果是CLI模式
if(php_sapi_name() === 'cli'){
//檢測CLI訪問時沒有帶自定義參數;
$path = isset($argv[1]) ? $argv[1] : '';
$depr = '/';
if (!empty($path)) {
$params = explode($depr , trim($path , $depr));
}
!empty($params) ? $_GET['g'] = array_shift($params) : "";
!empty($params) ? $_GET['m'] = array_shift($params) : "";
!empty($params) ? $_GET['a'] = array_shift($params) : "";
if ($params and count($params) > 1) {
// 解析剩余參數 并采用GET方式獲取
preg_replace('@(\w+),([^,\/]+)@e' , '$_GET[\'\\1\']="\\2";' , implode(',' , $params));
}
/*
D:\wamp\www\sx>D:\wamp\bin\php\php5.3.8/php cli.php group/module/action/a1/v1/a2/v2
Array
(
[g] => group
[m] => module
[a] => action
[a1] => v1
[a2] => v2
)
*/
// print_r($_GET);
// die;
}
```
## PHP-CLI來寫shell腳本
### PHP與Linux命令交互的幾個函數
**exec**
```sp
string exec ( string $command [, array &$output [, int &$return_var ]] )
echo exec('mkdir -p zhouzhou/1/2/3/') ."\n"; //創建目錄樹
echo exec('ls -l',$fileList) ; //本句只能輸出最后一條,但如果有第二個參數的話,就可以把輸出的結果作為數組元素扔進去;
echo "<pre />";
print_r($fileList); //把所有ls -l的結果都給了$fileList;
echo "<pre />";
die;
```
**shell_exec**
```sp
string shell_exec ( string $cmd )
$fileList = shell_exec('ls -l'); //$fileList是一個string格式,就等于linux命令在終端輸出的格式,保留了\s\n等換行符
```
**system**
```sp
string system ( string $command [, int &$return_var ] )
$fileList = system('ls -l') ; //本句只能輸出最后一條,但如果有第二個參數的話,就可以把輸出的結果作為數組元素扔進去;
```
**passthru**
```sp
void passthru ( string $command [, int &$return_var ] )
passthru('ls -l'); //直接執行并輸出
```
**popen**
```sp
resource popen ( string $command , string $mode )
/*
返回一個和 fopen() 所返回的相同的文件指針,只不過它是單向的(只能用于讀或寫)并且必須用 pclose() 來關閉。此指針可以用于 fgets(),fgets() 和 fwrite()。 當模式為 'r',返回的文件指針等于命里的 STDOUT,當模式為 'w',返回的文件指針等于命令的 STDIN。
如果出錯返回 FALSE。
*/
$fp = popen('ls -l',"r"); //popen打一個進程通道
while (!feof($fp)) {
$out = fgets($fp, 4096);
echo $out; //輸出的結果和passthru是一樣的;不過要循環的取出來;
}
pclose($fp);
```
**proc_open**
```sp
resource proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] )
$test = "ls";
$array = array(
array("pipe","r"), //標準輸入
array("pipe","w"), //標準輸出內容
array("pipe","w") //標準輸出錯誤
);
$fp = proc_open($test,$array,$pipes); //打開一個進程通道
echo stream_get_contents($pipes[1]); //為什么是$pipes[1],因為1是輸出內容
proc_close($fp);
//類似 popen() 函數, 但是 proc_open() 提供了更加強大的控制程序執行的能力。
```
- Apache
- 【Apache運維基礎(1)】Apache的安裝與使用
- 【Apache運維基礎(2)】主配置文件說明
- 【Apache運維基礎(3)】虛擬主機配置說明
- 【Apache運維基礎(4)】Apache的Rewrite攻略(1)
- 【Apache運維基礎(5)】Apache的Rewrite攻略(2).htaccess文件
- 【Apache運維基礎(6)】Apache的日志管理與分析
- 工具篇
- supervisor進程管理器
- Haproxy安裝與配置
- Nginx
- 【nginx網站性能優化篇(1)】gzip壓縮與expire瀏覽器緩存
- 【nginx網站性能優化篇(2)】反向代理實現Apache與Nginx的動靜分離(LNMPA)
- 【nginx網站性能優化篇(3)】反向代理實現負載均衡
- 【nginx網站性能優化篇(4)】理解nginx的高并發原理及其配置調優
- 【nginx運維基礎(1)】Nginx的編譯安裝與使用
- 【nginx運維基礎(2)】Nginx的配置文件說明及虛擬主機配置示例
- 【nginx運維基礎(3)】Nginx的編譯PHP
- 【nginx運維基礎(4)】Nginx的日志管理(日志格式與定時分割日志)
- 【nginx運維基礎(5)】Nginx的location攻略
- 【nginx運維基礎(6)】Nginx的Rewrite語法詳解
- 【nginx運維基礎(7)】配置SSL支持https訪問
- 【nginx運維基礎(8)】配置支持http2協議
- 【nginx運維基礎(9)】了解PHP-FPM 與 Nginx 的通信機制
- 其它
- Apache與Nginx下php隱藏http頭部版本信息的實現方法
- CURL與PHP-CLI的應用【CLI篇】
- CURL與PHP-CLI的應用【Curl篇】
- Linux之SAMBA共享服務
- 【Linux常識篇(1)】所謂的正向代理與反向代理
- 【Linux常識篇(2)】理解inode
- 【Linux常識篇(3)】文件及文件夾的ctime atime mtime的含義詳解
- centOS使用手記
- 服務器日志分析
- 高頻命令
- df
- mv
- gzip
- cp
- tar
- touch
- cat
- uniq
- nl
- more
- rmdir
- less
- mkdir
- head
- rm
- tail
- 五大查詢命令
- vi&vim
- ls與目錄結構
- grep
- awk
- sed
- 其他高頻命令