家庭仪表盘
我之前写过一些关于 PHP 的文章,因为我认为它是一种很棒的实用语言,可以用来编写您需要做的快捷操作。而且,它允许您使用 Web 浏览器作为界面,每个人都有 Web 浏览器。这对我家人来说非常方便,因为我可以为我通常需要从命令行执行的各种操作制作简单的 Web 界面。(当我出差参加会议,Plex 服务器需要重启,或者需要完成其他一些很难通过电话解释的事情时,这非常有用。)
我的“家庭仪表盘”与您的可能不同,但概念非常简单。PHP 允许您在服务器上执行本地函数,因此只要您可以创建一个 bash 脚本来完成您需要做的事情,就可以从您为家人创建的“仪表盘”启动它。这是我创建的仪表盘示例文件,您可以了解创建自定义页面来完成您需要做的事情有多么简单(请参见图 1,其中显示了仪表盘的屏幕截图)
<html><head><title>My Dashboard</title></head>
<body>
<h3>You need to enter some commands and possibly options,
↪or just press a button:<br />
<button onclick="window.location='lj.php?command=weather&
↪option=houston'">Weather</button>
<button onclick="window.location='lj.php?command=bing'">Bing
↪Photo</button>
<button onclick="window.location='lj.php?command=uname'">Kernel
↪Name</button>
<button onclick="window.location='lj.php?command=time'">Unix
↪Time</button>
</h3>
<?php
$command = $_GET['command'];
$option = $_GET['option'];
switch ($command)
{
case "weather":
echo file_get_contents("http://wttr.in/$option");
break;
case "time":
echo time() . " <-- that's how I read time! I'm a robot!";
break;
case "bing":
$json = json_decode(file_get_contents("http://www.bing.com/
↪HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"), TRUE);
$url = "http://bing.com" . $json['images']['0']['url'];
echo "Here is the image of the day:\n";
echo "<img src=$url />";
break;
case "uname":
echo shell_exec("uname -a");
break;
default:
echo "<h1>Press a button!</h1>";
}
?>
</body></html>

图 1. 我的仪表盘很简单,但它只是底层代码的前端。
首先,将该代码复制粘贴到一个名为 lj.php 的文件中,并将其保存到您的本地 Web 服务器上。服务器需要激活 PHP,但我将其留给读者自行设置。我之前写过关于安装 LAMP 堆栈的文章,因此设置一个运行并支持 PHP 的 Web 服务器应该不会太困难(请参阅我 2014 年 12 月刊的文章“面向非开发人员的 PHP”)。此外,将文件命名为“lj.php”非常重要,因为如果您查看代码,它会引用自身。如果您将其命名为其他名称,只需更改 HTML/PHP 代码中的引用即可。
在了解代码的工作原理之前,先测试一下并观看它的运行。如果您无法自行托管该文件,但又想查看它的实际效果,可以使用我的服务器进行测试。只需访问此处,它应该会将您重定向到此文件的托管版本。单击按钮,看看您是否能弄清楚发生了什么。您能获取您所在地区的本地天气预报吗?
GET 和 Switch Stuff 是什么?可以为您需要完成的每个操作创建一个单独的 PHP 文件。但是,这会产生大量 PHP 文件,并且仍然无法让您接收输入以在 PHP 文件本身中使用。我希望我的家人只有一个 URL,并且我希望将所有代码都放在一个文件中。这样更方便。首先,我将解释 $_GET
变量的作用。
当您单击页面上的按钮时,您应该查看浏览器上的地址栏。例如,当您单击天气按钮时,您应该在地址栏中看到以下内容:http://your.server.here/lj.php?command=weather&option=houston。
末尾的内容是您告诉 PHP 脚本您希望它显示的信息的方式。您分配的所有变量都放入一个名为 $_GET
的数组中。因此,在上面的天气示例中,我分配了两个变量。要在 PHP 脚本中引用它们,您可以使用 $_GET
数组。因此,在上面的 URL 中,分配了这两个变量
$_GET['command'] = "weather";
$_GET['option'] = "houston";
并且,您可以在 PHP 代码中使用这些变量。请注意,我实际上已将这两个变量分配给标准变量名,以便稍后更容易引用它们。您可以通过更改 URL 中的信息来更改发送到 PHP 脚本的变量。这使得脚本可以动态地工作,并根据您提供的输入提供输出。事实上,按下这些按钮之所以有效,唯一的原因是它加载了带有已到位参数的页面!看看您现在是否可以通过更改 URL 中的“option”变量并加载页面来获取本地天气预报。很酷,不是吗?
不仅仅是天气由于您可以通过 URL 将变量发送到 PHP 脚本,这意味着您的仪表盘可以做的不仅仅是显示天气。根据变量,您可以使用 PHP 中的 switch
结构调用不同的命令。它类似于其他语言中的 CASE
语句,逻辑非常简单。
您在从 $_GET
数组分配的 $command
变量上运行 switch
语句。如果变量与列为“case”的任何选项匹配,它将执行该部分中的代码,然后您 break;
跳出 switch 结构。如果 $command
变量与任何 case
选项都不匹配,则 switch
执行末尾的 default:
部分。在本例中,它是按按钮的消息。
让我们看一下每个部分,了解当您按下按钮(或手动在 URL 中输入命令)时会发生什么。
PHP 之前的部分如果您将标准 HTML 放入 PHP 文件中,并且没有将其括在 <?PHP ?> 标记之间,它只会将其作为 HTML 代码发送到 Web 浏览器。因此,lj.php 文件的顶部只是纯 HTML。文本显示在 <h3> 标记中,按钮是使用一小段 JavaScript 创建的,该 JavaScript 允许它们加载指定的 URL。如果按钮和 JavaScript 让您感到不舒服,则可以使用指向您想要的位置的标准文本链接。我只是喜欢按钮,因为它们看起来很酷。
重要的是要认识到,按钮除了加载带有在 URL 中分配的 $_GET
变量的页面之外,什么也没做。按钮本身不执行代码,也不是什么花哨的东西。您可以手动键入 URL 并实现相同的目的。但是,如果您的家人让您制作链接或按钮,他们会很感激,因为单击比键入又长又复杂的 URL 容易得多!
如果您单击天气按钮,或手动输入 URL 以将 $_GET['command']
和 $_GET['option']
变量与 weather
命令一起发送到脚本,则 switch 语句将执行 case "weather":
部分内的代码。
这是一个非常简单的命令,只是回显(在屏幕上打印)从获取网页的结果。PHP 中的 file_get_contents
函数将获取本地文件或 Internet 上的文件的内容。在本例中,您可以使用 $option
变量创建 URL。如果您单击该按钮,您会注意到 $option
设置为“houston”,但您可以手动更改 URL 以获取您当地的天气。它将接受城市名称、邮政编码甚至机场代码。
脚本的天气部分是唯一查看 $option
变量的部分,但是可以从 URL 分配任意数量的变量。如果您分配了一个变量但未使用它,则无害,它只是被忽略。
“时间”部分不会返回您期望时间按钮返回的结果。事实上,我将加载该页面的按钮标记为“Unix 时间”,因为我使用了 PHP 中的 time()
函数,该函数显示自 1970 年 1 月 1 日以来经过的秒数。这看起来可能不是一个非常有用的数字,但它在编程时非常方便,因为您不必解析小时、分钟等。您可以单击(或刷新)页面几次,您应该会看到数字递增。
UNIX 时间(有时称为 Epoch 时间)很有趣,可以玩玩,虽然这个例子不是很有用,但我还是想将其包含在内,以便您可以看到 time()
命令的工作原理,以及 echo
命令。如果您查看,在 time()
函数之后有一个句点。它将两个项目连接成一个字符串并一起显示。如果您单击该按钮,您将明白我的意思。
Bing 每日照片总是很棒(图 2)。真的,Microsoft 在获取令人难以置信的照片方面做得非常出色,我喜欢看它们。由于 URL 总是不同的,因此这是一种展示如何将 JSON 加载到变量中,然后提取数组元素的绝佳方式。不要让看起来可怕的代码吓到您;JSON 非常酷。基本上,您从该长 Bing URL 加载 JSON 并将其放入 PHP 数组中。然后,您从该数组的内容中形成照片的 URL。这是一个代码片段,您可以使用它以更易读的形式查看数组
<?php
$json = json_decode(file_get_contents("http://www.bing.com/
↪HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"), TRUE);
echo "<pre>";
print_r($json);
echo "</pre>";
?>

图 2. Bing 照片总是如此酷。
如果您没有服务器,请访问此处查看 PHP 文件的结果。您可以看到我在哪里获得了构建图像 URL 的信息,并且在 switch
语句中,您可以看到它只是根据该 URL 加载图像。JSON 是不是很酷?
switch
语句的这一部分功能强大,但也有些可怕。如果您单击“内核名称”按钮,您可以看到它执行 switch
语句的 uname
部分中的代码。使用 shell_exec
命令,您可以在本地服务器上执行文件并在浏览器窗口中显示结果。这很强大,因为它意味着您可以让您的家人通过单击按钮来执行本地 bash 脚本。但这有点可怕,因为您正在通过单击按钮在服务器上执行本地命令!
脚本以 Web 浏览器的权限执行,因此,例如,在运行 Apache 的 Ubuntu 中,www-data 用户将执行该命令。如果该用户没有权限在脚本中执行某些操作,则脚本将失败。这就是“能力越大,责任越大”的事情之一。它可能非常有用,但也可能非常危险,尤其是在您的服务器暴露于 Internet 的情况下!
故障排除每当我编写 PHP 代码时,我都会犯错误。通常,它是一个遗忘的分号或不匹配的括号。当您加载页面时,突然它是空白的而不是显示错误时,可能会非常烦人。在我上次写的关于 PHP 的文章中,我展示了如何打开 PHP 错误,以便您可以在 Web 浏览器中看到哪里出了问题。我不再那样做了,因为当事情运行良好时,看到 PHP 警告很烦人。所以我现在做的是从命令行运行 php
。如果代码已损坏,它将在您的命令行上显示错误,您不必担心在 Web 浏览器中打开和关闭错误日志记录。例如,在示例 lj.php 文件中,只需转到它存储的文件夹并键入
php lj.php
服务器会将 HTML 转储到您的命令行,就像它是 Web 浏览器一样。如果出现错误,它会告诉您哪里做错了。我更喜欢这种错误检查方法,而不是在 Web 浏览器中获取错误通知,但如果您更喜欢在浏览器上看到它们,请回顾我 2014 年 12 月刊的 PHP 文章,了解如何激活错误日志记录。
就像上次一样,我只是让您尝尝使用 PHP 和一点创意可以完成的各种事情。如果您提出了自己有趣的仪表盘,我很乐意看到它,即使只是一个屏幕截图。(不要将您的仪表盘暴露于 Internet,尤其是在它使用 shell_exec
语句控制您的本地服务器的情况下!)请随时通过电子邮件 shawn@linuxjournal.com 与我联系,但请务必在主题行中注明“DASHBOARD”,否则我可能会认为它是垃圾邮件。我收到太多该死的垃圾邮件了!