家庭仪表盘

作者:Shawn Powers

我之前写过一些关于 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?你怎么敢加载 Microsoft 页面!

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”,否则我可能会认为它是垃圾邮件。我收到太多该死的垃圾邮件了!

Shawn 是 Linux Journal 的副编辑,并且从一开始就接触 Linux。他对开源充满热情,并且热爱教学。他还喝太多咖啡,这经常在他的写作中体现出来。

加载 Disqus 评论