More and more in the Information Technology field are we asked to put on various hats and fill multiple roles in our daily jobs. Not only are many of us given the task to create and maintain a web site, but also to maintain the server its hosted on. Usually when maintaining a server you need to know how to write scripts and small programs to automate tasks. A lot of these scripts are written in Perl, Bash, or some other scripting language. Now I’m not against learning new programming languages at all, but did you know that not only can you use PHP to write great web applications, but you can use PHP from the command line as well? You can use the PHP that you already know and love to keep that server running great, all from the command line!
我们要求在信息技术领域中越来越多地戴上帽子,并在我们的日常工作中扮演多个角色。 我们中的许多人不仅承担创建和维护网站的任务,而且还承担维护其托管服务器的任务。 通常,在维护服务器时,您需要知道如何编写脚本和小型程序来自动执行任务。 其中许多脚本是用Perl,Bash或其他脚本语言编写的。 现在我完全不反对学习新的编程语言,但是您知道吗,您不仅可以使用PHP编写出色的Web应用程序,而且还可以从命令行使用PHP? 您可以使用已经知道并且喜欢使用PHP来使服务器保持良好的运行状态,而这一切都可以通过命令行完成!
In this article we’ll look at the advantages of using PHP CLI. I’ll show you how to test PHP’s Command Line Interface / Interpreter (CLI) on your server, and then we’ll look at some of the options available for PHP CLI including the interactive shell and how to create executable scripts. Finally, I’ll give you a couple of examples of scripts to use to maintain your server written in PHP.
在本文中,我们将探讨使用PHP CLI的优势。 我将向您展示如何在服务器上测试PHP的命令行界面/解释器(CLI),然后我们将研究PHP CLI可用的一些选项,包括交互式外壳程序以及如何创建可执行脚本。 最后,我将为您提供一些脚本示例,以用于维护用PHP编写的服务器。
One of the biggest advantages of using PHP CLI instead of some other scripting language is the ability to reuse code from previous projects in your script. Whether it be a database class or a function that you created or maybe a file parsing program, with PHP CLI you don’t have to rewrite any of your code.
使用PHP CLI代替某些其他脚本语言的最大优势之一是能够重用脚本中以前项目中的代码。 无论是数据库类,创建的函数还是文件解析程序,使用PHP CLI都无需重写任何代码。
You can also automate many tasks written with PHP CLI with CRON. If you have never used CRON before, it’s a daemon program that runs specified scripts at specific times on your server. Need to generate a report for the sales department on Mondays, Wednesdays, and Fridays? Write a PHP script to do it, throw it into a CRON job, and sit back and relax while PHP and CRON do the work for you.
您还可以使用CRON自动执行用PHP CLI编写的许多任务。 如果您以前从未使用过CRON,则它是一个守护程序,可在特定时间在服务器上运行指定的脚本。 是否需要在星期一,星期三和星期五为销售部门生成报告? 编写一个PHP脚本来完成此任务,将其投入CRON工作,然后坐下来放松,同时PHP和CRON为您完成工作。
运行PHP CLI脚本 (Running PHP CLI Scripts)
If you are running a recent version of PHP, chances are you already have PHP CLI installed on your system. If the examples in this article don’t work for you, then you’ll probably need to recompile PHP with the --enable-cli
option or reinstall a PHP package that contains that option. The easiest way to test to see if everything is working is to open up a new terminal window or SSH session to your server or computer and from the command line type in php -v
.
如果您正在运行最新版本PHP,则很可能已经在系统上安装了PHP CLI。 如果本文中的示例不适合您,则可能需要使用--enable-cli
选项重新编译PHP或重新安装包含该选项PHP软件包。 测试是否一切正常的最简单方法是打开新的终端窗口或与服务器或计算机的SSH会话,并从命令行键入php -v
。
Stephens-Laptop:~ sthorpe$ php -v
PHP 5.3.8 (cli) (built: Dec 5 2011 21:24:09)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
Let’s try a quick example where we will run an actual PHP file from the command line. Create a file called test.php
with the following code using your favorite editor:
让我们尝试一个简单的示例,在该示例中,我们将从命令行运行实际PHP文件。 使用您喜欢的编辑器使用以下代码创建一个名为test.php
的文件:
<?php
$str = "SitePoint is the best!";
echo $str . "n";
To execute the script, all you have to do is type in php test.php
and you’ll see the output on the command line.
要执行脚本,您所要做的就是输入php test.php
然后您将在命令行中看到输出。
Stephens-Laptop:~ sthorpe$ php test.php
SitePoint is the best!
A more preferred method of running PHP scripts on the command-line is to change the permissions mode of the script and place #!/usr/bin/php
at the top of the file before the opening <?php
tag (your path to PHP may be different depending on your system’s configuration). To accomplish this, you’ll use the chmod
command on UNIX-based systems.
在命令行上运行PHP脚本的一种更可取的方法是更改脚本的权限模式,并将#!/usr/bin/php
放在文件的顶部,然后打开<?php
标记(您PHP路径)可能会有所不同,具体取决于您的系统配置。 为此,您将在基于UNIX的系统上使用chmod
命令。
#!/usr/bin/php
<?php
$filepath = exec("pwd");
echo "You are in the $filepath directory.n";
Stephens-Laptop:~ sthorpe$ chmod +x pwd.php
Stephens-Laptop:~ sthorpe$ ./pwd.php
You are in the ~ directory.
CLI选项和Interactive Shell (CLI Options and the Interactive Shell)
I’ve already shown you one of PHP’s command-line options earlier, -v
which gives you the version number of PHP installed on your system, but there are more options available. For example, if you wanted to share the code from a script you wrote with someone as web page and have it syntax highlighted for better readability, you can use the -s
option. PHP will output the appropriate HTML code.
前面已经向您展示了PHP的命令行选项之一-v
,它为您提供了系统上安装PHP的版本号,但是还有更多选项可用。 例如,如果要共享与某人作为网页编写的脚本中的代码,并突出显示其语法以提高可读性,则可以使用-s
选项。 PHP将输出适当HTML代码。
Stephens-Laptop:~ sthorpe$ php -s test.php < test.html
When viewed in a web browser, the resulting test.html
presents the highlighted code:
在网络浏览器中查看时,生成的test.html
显示突出显示的代码:
Another helpful option is -l
to check your scripts for any syntax errors. If no errors are found in the file, PHP will report back there were no syntax errors. Otherwise PHP will report the error it found and on which line it occurred.
另一个有用的选项是-l
检查脚本是否存在语法错误。 如果在文件中未发现错误,PHP将报告没有语法错误。 否则,PHP将报告发现的错误以及发生在哪一行。
Stephens-Laptop:~ sthorpe$ php -l broken.php
PHP Parse error: syntax error, unexpected T_VARIABLE in broken.php on line 3
Errors parsing broken.php
In addition to the numerous options available, with PHP CLI you can test out ideas in PHP code right from the shell without having to create any files at all! This is useful when you want to see what the results of a function might be. To run PHP’s interactive shell use -a
. PHP will report back “Interactive shell” and the prompt will change to php >
. From this point forward you can just type your code and PHP will execute it immediately. To exit the shell, you can either press CTRL + D or call exit
.
除了可用的众多选项之外,借助PHP CLI,您可以直接从外壳中以PHP代码测试思想,而无需创建任何文件! 当您想查看一个函数的结果可能是有用的。 要运行PHP的交互式shell,请使用-a
。 PHP将报告“ Interactive shell”,并且提示符将更改为php >
。 从现在开始,您只需键入代码,PHP就会立即执行它。 要退出外壳,可以按CTRL + D或调用exit
。
Stephens-Laptop:~ sthorpe$ php -a
Interactive shell
php > echo 2 + 2;
4
php > exit;
获取输入 (Getting Input)
With CLI programming, you have two options for input functionality. The first option is to pass arguments to your script directly from the command line. The second option is reading the input from the keyboard (standard input) from the user running the script.
使用CLI编程,您有两个输入功能选项。 第一种选择是直接从命令行将参数传递给脚本。 第二个选项是从运行脚本的用户读取键盘输入(标准输入)。
To accept arguments into your script, you’ll use the predefined superglobal variables $_SERVER["argc"]
and $_SERVER["arvc"]
. Create a file called arguments.php
containing the code below:
要接受脚本中的参数,您将使用预定义的超全局变量$_SERVER["argc"]
和$_SERVER["arvc"]
。 创建一个名为arguments.php
的文件,其中包含以下代码:
#!/usr/bin/php
<?php
echo "There are " . $_SERVER["argc"] . " arguments:n";
foreach($_SERVER["argv"] $arv) {
echo "t" . $arv . "n";
}
$_SERVER["argc"]
contains the number of arguments that were passed to the script, and $_SERVER["argv"]
is an array containing all the values of those arguments. You will always have at least one argument since the file name itself is considered the first argument.
$_SERVER["argc"]
包含传递给脚本的参数数量, $_SERVER["argv"]
是包含这些参数的所有值的数组。 由于文件名本身被视为第一个参数,因此您将始终至少有一个参数。
Make the file executable and pass in a few arguments with a space in between each one. The script will display the total number of arguments and list each one.
使文件可执行,并传入几个参数,每个参数之间应有一个空格。 该脚本将显示参数总数并列出每个参数。
Stephens-Laptop:~ sthorpe$ php arguments.php SitePoint Rocks
There are 3 arguments
arguments.php
SitePoint
Rocks
Accepting input from standard input lets you create interactive scripts which can prompt for specific information. Create a file called keyboard.php
with the following code:
通过接受来自标准输入的输入,您可以创建可以提示输入特定信息的交互式脚本。 使用以下代码创建一个名为keyboard.php
的文件:
#!/usr/bin/php
<?php
echo "Hi There! what is your favorite web site?n";
$site = fread(STDIN, 80);
$site = trim($site);
if ($site != "SitePoint") {
echo "Are you sure that one is your favorite?n";
}
else {
echo "I knew it! Me too!n";
}
In this example we are using the fread()
function just as we would to read in a file, but in this case the handle is the PHP predefined constant STDIN
. Once again make the file executable and run the file; hopefully your output will be the same as mine.
在这个例子中,我们就像读取文件一样使用fread()
函数,但是在这种情况下,句柄是PHP预定义的常量STDIN
。 再次使该文件可执行并运行该文件; 希望您的输出与我的输出相同。
Stephens-Laptop:~ sthorpe$ php keyboard.php
Hi There! what is your favorite web site?
SitePoint
I knew it! Me too!
一些PHP CLI示例 (Some PHP CLI Examples)
When monitoring a server, one thing worth keeping track of is your available disk space. These days hard drives are so huge that you wouldn’t think that there was a way you could possibly fill up all that space, but trust me… it can happen when you least expect it. Maybe your log rotation process broke and you didn’t realize it, or your temp directory grew out of control. Here’s an example you can use to keep an eye on your server’s disk space:
监视服务器时,值得跟踪的一件事是您的可用磁盘空间。 如今,硬盘驱动器是如此之大,以至于您不会想到有一种方法可以填满所有空间,但是请相信我……当您最不期望它时,它就会发生。 也许您的日志轮换过程中断了,但您没有意识到,或者您的临时目录失去了控制。 您可以使用以下示例来监视服务器的磁盘空间:
#!/usr/bin/php
<?php
// config options
$disk = "/dev/disk0s2";
$threshold = 90;
$emailAddr = "you@example.com";
$emailName = "Your Name Here";
exec("df -h " . $disk, $output);
foreach($output as $line){
$info = strstr($line, $disk);
if ($info != "") {
break;
}
}
$pos = stripos($info, "%");
$pos = $pos - 3;
$used = substr($info, $pos, 3);
if ($used >= $threshold) {
mail($emailAddr, "System HD Notification", "Main disk is at " . $used . "%" , "From: $emailName");
}
The function exec()
executes a command in the command line and accepts two parameters: the first is the actual command (in this case df
which displays disk space information), and the second is an array reference that is filled with the command’s output. The $disk
variable holds the path of the disk you want to monitor (in my case it’s /dev/disk0s2
). The df
command outputs various other data than just disk space used, so we’ll only be looking for specific information from the $output
array.
函数exec()
在命令行中执行命令并接受两个参数:第一个是实际命令(在本例中为df
,它显示磁盘空间信息),第二个是填充有该命令输出的数组引用。 $disk
变量保存要监视的磁盘的路径(在我的情况下为/dev/disk0s2
)。 df
命令会输出各种其他数据,而不仅仅是已使用的磁盘空间,因此我们只从$output
数组中查找特定信息。
The code continues by looping through the array and using the strstr()
function to find the desired disk and break out of the loop once it’s been found. I strip out the part of the string that contains the percentage of disk space left with using substr()
and compare it to a predetermined value, in this case if the hard drive usage reaches 90% or more. If so, the script sends an email alerting me with the information.
通过遍历数组并使用strstr()
函数查找所需的磁盘并在找到后退出循环,继续执行代码。 我使用substr()
去除了包含剩余磁盘空间百分比的字符串部分,并将其与预定值进行比较,在这种情况下,如果硬盘使用率达到90%或更高。 如果是这样,脚本将发送一封电子邮件,提醒我有关信息。
You could have this quick script run as a cron job every 30 minutes or so and it should give you some peace of mind.
您可以每30分钟左右将这个快速脚本作为cron作业运行,它应该使您放心。
Another common task when maintaining a server is to insure that you have a constant backup of files and folders. If some sort of version control of back-up service isn’t available for whatever reason, this next script can be used to back up some folders and a database and send them to an off-site SFTP server.
维护服务器时的另一个常见任务是确保文件和文件夹的备份持续不断。 如果出于某种原因无法使用某种形式的备份服务版本控制,则可以使用下一个脚本来备份一些文件夹和数据库,并将其发送到异地SFTP服务器。
#!/usr/bin/php
<?php
// remote SFTP connection credentials
$sftpServerIP = "10.0.0.1";
$sftpUsername = "sftpuser";
$sftpPassword = "hushhush";
$sftpTarget = "/home/sftpuser";
// mail notification config
$emailAddr = "you@example.com";
$emailName = "Your Name Here";
// MySQL database connection credentials
$mysqlUsername = "dbuser";
$mysqlPassword = "secret";
$mysqlDatabase = "myDatabase";
// list of directories and files to back up
$files = array(
"/home/username/important-file.txt",
"/home/username/special-folder",
"/var/spool/another-folder");
// create temporary directory and copy files/directories to it
$tmpFolder = "/tmp/" . uniqid();
mkdir($tmpFolder, 0700);
foreach ($files as $f) {
exec("cp -r $f $tmpFolder/");
}
// dump the database content
exec("mysqldump -u $mysqlUsername -p$mysqlPassword $mysqlDatabase > $tmpFolder/backup.sql");
// compress the backup
exec("tar -czf $tmpFolder.tgz $tmpFolder/*");
// establish the sftp connection
$session = ssh2_connect($sftpServerIP, 22);
if ($session === false) {
mail($emailAddr, "System Backup", "Could not connect to SFTP server", "From: $emailName");
exit;
}
$result = ssh2_auth_password($session, $sftpUsername, $sftpPassword);
if ($result === false) {
mail($emailAddr, "System Backup", "Could not authenticate to SFTP server", "From: $emailName");
exit;
}
$sftp = ssh2_sftp($session);
if ($sftp === false) {
mail($emailAddr, "System Backup", "Could not initialize SFTP subsystem", "From: $emailName");
exit;
}
// transfer the backup file
$date = date("D");
$upload = file_put_contents(
"ssh2.sftp://" . $sftp . $sftpTargetDir . "/backup-$date.tgz",
file_get_contents("$tmpFolder.tgz"));
if ($upload) {
mail($emailAddr, "System Backup", "Your files has been backed up successfully", "From: $emailName");
}
else {
mail($emailAddr, "System Backup", "Something went wrong with the upload of the backup", "From: $emailName");
}
// clean up the local temp backups
exec("rm -r $tmpFolder $tmpFolder.tgz");
Again we use the exec()
function to execute other programs and commands from within our PHP script, such as mysqldump
to dump the database content and tar
to compress the backup folder into an archive. into the variable we defined before. Connecting to the SFTP server uses PHP’s SSH2 extension, so you’ll need to have that extension installed. A good write up can be found in Kevin van Zonneveld’s blog. The code shouldn’t be too difficult to modify if you want to use a pure solution like phpseclib or even an older (and insecure) protocol like FTP. Regardless of your approach, the sample highlights some of the benefits of scripting such tasks with PHP.
再次,我们使用exec()
函数从PHP脚本中执行其他程序和命令,例如mysqldump
来转储数据库内容,而tar
将压缩文件夹压缩到存档中。 到我们之前定义的变量中。 连接到SFTP服务器使用PHP的SSH2扩展名 ,因此您需要安装该扩展名。 可以在Kevin Van Zonneveld的博客中找到不错的文章 。 如果您想使用像phpseclib这样的纯解决方案,甚至是像FTP这样的旧的(而且是不安全的)协议,那么修改代码就不会太困难。 无论采用哪种方法,该示例都突出了使用PHP编写此类任务的一些好处。
摘要 (Summary)
In this article we explored using PHP from the command line to write server maintenance scripts. I talked about the advantages of using PHP CLI, including the ability to automate your scripts. We went over some neat options available, like the ability to test your scripts for syntax errors and using interactive mode. We also learned about the different input functionality available, including accepting input straight from the keyboard. I then gave you two real world examples of scripts to use to maintain your own servers which included a hard drive monitoring script and a backup script.
在本文中,我们探索了如何从命令行使用PHP编写服务器维护脚本。 我谈到了使用PHP CLI的优点,包括使脚本自动化的能力。 我们介绍了一些可用的简洁选项,例如能够测试脚本的语法错误和使用交互模式的功能。 我们还了解了可用的不同输入功能,包括直接从键盘接受输入。 然后,我为您提供了两个真实的脚本示例,用于维护您自己的服务器,其中包括硬盘驱动器监视脚本和备份脚本。
I hope this article has given you some ideas and knowledge that will help you in the future when you are given the task to maintain that server, and I hope you can also use these CLI example scripts as a bases to create your own maintenance scripts.
我希望本文为您提供了一些想法和知识,这些知识和知识将在将来承担维护该服务器的任务时为您提供帮助,并且希望您也可以使用这些CLI示例脚本作为基础来创建自己的维护脚本。
Image via Chengyuan Yang / Shutterstock
图片来自杨成元 / Shutterstock
翻译自: https://www.sitepoint.com/maintaining-your-server-with-command-line-php/