创建移动应用移动应用

tech2023-11-21  64

创建移动应用移动应用

It seems like everyone these days is texting away on their mobile phone or updating their social network status every 5 minutes. It’s no surprise that the convenience of being able to access the Internet from anywhere at any time has made sharing messages and pictures so popular. I can’t imagine going anywhere without my cell phone on the off chance that something interesting might happen and I can document it as if I were the first news reporter on the scene.

如今,似乎每个人都每隔5分钟通过手机发短信或更新社交网络状态。 毫不奇怪的是,能够随时随地访问Internet的便利使共享消息和图片如此受欢迎。 我无法想象在没有手机的情况下去任何地方都可能会发生一些有趣的事情,并且我可以记录下来,就好像我是现场的第一位新闻记者一样。

This is the first article in a two-part series in which I will show you how to create a photo blog as part of your personal website which you can update from your phone simply by sending an email. You’ll write a script to check the inbox of an email account for new messages using POP3; the script will extract the messages’ subject line, body text, and attachments and update a database accordingly. You can then pull the information from the database for display on your blog, in a sidebar, or however else you see fit.

这是分两部分的系列文章中的第一篇,其中我将向您展示如何创建一个图片博客作为您个人网站的一部分,您可以通过发送电子邮件从手机中进行更新。 您将编写一个脚本,以使用POP3检查电子邮件帐户的收件箱中是否有新消息。 该脚本将提取邮件的主题行,正文和附件,并相应地更新数据库。 然后,您可以从数据库中提取信息,以显示在博客上,边栏中,或者其他您认为合适的信息。

Rather than developing a mobile application such as for Android or iPhone, the code will run on a web server and in effect be platform independent. With regard to PHP, I will be using the IMAP and Imagick extensions so you’ll want to make sure they are installed before you get started.

该代码不会开发用于Android或iPhone的移动应用程序,而是将在Web服务器上运行,并且实际上与平台无关。 关于PHP,我将使用IMAP和Imagick扩展,因此在开始之前,您需要确保已安装它们。

安全注意事项 (Security Considerations)

For security reasons, you will obviously need some type of authentication. To achieve this you first need to setup a private email account for the web server that only you know about. This is the account that will receive the updates. Then, you will need a second email account for your mobile device to send updates. I’ll be using the private email not@liberty2.say and the public email mobile@example.com in the code throughout the articles.

出于安全原因,您显然需要某种类型的身份验证。 为此,您首先需要为您唯一了解的Web服务器设置一个私人电子邮件帐户。 这是将接收更新的帐户。 然后,您将需要第二个电子邮件帐户供您的移动设备发送更新。 在整篇文章的代码中,我将使用私人电子邮件not@liberty2.say和公共电子邮件mobile@example.com 。

The level of security you can apply to the server email account will vary depending on what administrative privileges you have. In a best-case scenario, you want your mail server to reject all incoming mail on the account except from your mobile’s public address. In a worst-case scenario, you want to at least make sure its spam filter is set to the highest possible setting and add your mobile address to its whitelist.

可以应用到服务器电子邮件帐户的安全级别取决于您所拥有的管理特权。 在最佳情况下,您希望邮件服务器拒绝该帐户上的所有传入邮件,但不包括您手机的公共地址。 在最坏的情况下,您至少要确保将其垃圾邮件过滤器设置为最高设置,并将您的移动地址添加到白名单中。

As an added layer of security, every email received by not@liberty2.say will be assigned a unique token. The token will then be sent to your phone along with a brief summary of the message and ask you for approval. To update your blog, you’d simply send an email, wait for the auto-reply and then open the provided link to approve the update. The auto-reply will be sent by a script that executes every few minutes as a cron job or, if you have access to the mail server itself, you can opt to use something like procmail or maildrop.

为了增加安全性, not @ liberty2.say收到的每封电子邮件都将分配一个唯一的令牌。 然后,令牌将与消息的简短摘要一起发送到您的手机,并要求您批准。 要更新博客,您只需发送电子邮件,等待自动回复,然后打开提供的链接以批准更新。 自动答复将通过脚本发送,该脚本每隔几分钟作为cron作业执行一次,或者,如果您有权访问邮件服务器本身,则可以选择使用procmail或maildrop之类的东西。

With these security measures in place, you can be assured that nothing will ever be published without your consent.

有了这些安全措施,您可以放心,未经您的同意将不会发布任何内容。

数据库 (Database)

You need at least three tables for this project: the blog_posts table which will store a blog id, blog title, body text and a timestamp; the images table which will store an image id, a reference to a blog id, and a file path where the image is stored on the server; and the pending table which will store a message id referring to the message number in the inbox, a unique 32-character MD5 token, and a flag to indicate the approval status.

此项目至少需要三个表:blog_posts表,它将存储博客ID,博客标题,正文和时间戳; images表将存储图像ID,对博客ID的引用以及在服务器上存储图像的文件路径; 还有待处理表,该表将存储引用收件箱中消息号的消息ID,唯一的32个字符的MD5令牌以及指示批准状态的标志。

These are the CREATE TABLE statements for the database:

这些是数据库的CREATE TABLE语句:

CREATE TABLE blog_posts ( post_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, title VARCHAR(100) NOT NULL, body TEXT NOT NULL, create_ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (post_id) ); CREATE TABLE images ( image_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, post_id INTEGER UNSIGNED NOT NULL, image_path VARCHAR(200) NOT NULL, PRIMARY KEY (image_id), FOREIGN KEY (post_id) REFERENCES blog_posts(post_id) ); CREATE TABLE pending ( message_id INTEGER UNSIGNED NOT NULL, token CHAR(32) NOT NULL, is_valid ENUM('Y','N') DEFAULT 'N', PRIMARY KEY (message_id) );

检索电子邮件 (Retrieving Email)

When it comes to retrieving email, you have the option of connecting with IMAP or POP3. The main difference between the two is in the method of mail storage. POP3 expects you to store mail on your own computer, so it only offers a way for you to download new mail and then the server’s copy is deleted. IMAP on the other hand is more like “web mail” in the sense that all the mail is stored and retained on the server which you access by connecting to remotely, and so it provides additional functionality such as folder management. IMAP is understandably more complex, which you can see for yourself by comparing the RFCs for the two protocols.

在检索电子邮件时,您可以选择与IMAP或POP3连接。 两者之间的主要区别在于邮件存储方法。 POP3希望您将邮件存储在自己的计算机上,因此它仅提供一种下载新邮件的方式,然后删除服务器的副本。 另一方面,IMAP更像“网络邮件”,因为所有邮件都存储和保留在您通过远程连接访问的服务器上,因此它提供了诸如文件夹管理之类的附加功能。 可以理解,IMAP更为复杂,您可以通过比较两种协议的RFC来亲自了解。

For all intents and purposes, POP3 will do the trick since you have no need for any special functionality. PHP provides functions for working with email protocols, including POP3, with its IMAP extension.

出于所有目的和目的,POP3可以解决问题,因为您不需要任何特殊功能。 PHP提供了使用电子邮件协议(包括POP3及其IMAP扩展名)的功能。

Documentation on many of the extension’s functions is spotty, and because of that they’re not easy to use. Luckily a set of wrapper functions were written and posted in the user contributed notes by Wil Barath which provide an API that’s much easier to use. The following class is based on Barath’s code and should be copied and saved as POP3.php:

有关扩展功能的许多功能的文档不完整,因此不易使用。 幸运的是,Wil Barath在用户提供的注释中编写并发布了一组包装函数,这些注释提供了更易于使用的API。 下列类基于Barath的代码,应复制并另存为POP3.php:

<?php class POP3 { private $conn; // make connection public function __construct($host, $user, $pass, $folder = "INBOX", $port = 110, $useSSL = false) { $ssl = ($useSSL) ? "" : "/novalidate-cert"; $mailbox = sprintf("{%s:%d/pop3%s}%s", $host, $port, $ssl, $folder); $this->conn = imap_open($mailbox, $user, $pass); } // close connection and trigger expunge public function __destruct() { imap_close($this->conn, CL_EXPUNGE); } // retrieve a list of messages public function listMessages($msgNum = "") { $msgList = array(); if ($msgNum) { $range = $msgNum; } else { $info = imap_check($this->conn); $range = "1:" . $info->Nmsgs; } $response = imap_fetch_overview($this->conn, $range); foreach ($response as $msg) { $msgList[$msg->msgno] = (array)$msg; } return $msgList; } // delete a message public function deleteMessage($msgNum) { return imap_delete($this->conn, $msgNum); } // parse headers into usable code public function parseHeaders($headers) { $headers = preg_replace('/rns+/m', "", $headers); preg_match_all('/([^: ]+): (.+?(?:rns(?:.+?))*)?rn/m', $headers, $matches); foreach ($matches[1] as $key => $value) { $result[$value] = $matches[2][$key]; } return $result; } // separate MIME types public function mimeToArray($msgNum, $parseHeaders = false) { $mail = imap_fetchstructure($this->conn, $msgNum); $mail = $this->getParts($msgNum, $mail, 0); if ($parseHeaders) { $mail[0]["parsed"] = $this->parseHeaders($mail[0]["data"]); } return $mail; } // separate mail parts public function getParts($msgNum, $part, $prefix) { $attachments = array(); $attachments[$prefix] = $this->decodePart($msgNum, $part, $prefix); // multi-part if (isset($part->parts)) { $prefix = ($prefix) ? $prefix . "." : ""; foreach ($part->parts as $number => $subpart) { $attachments = array_merge($attachments, $this->getParts($msgNum, $subpart, $prefix . ($number + 1))); } } return $attachments; } // fetch the body of an email with one part public function fetchBody($msgNum = "") { return imap_fetchbody($this->conn, $msgNum, 1); } // decode attachments public function decodePart($msgNum, $part, $prefix) { $attachment = array(); if ($part->ifdparameters) { foreach ($part->dparameters as $obj) { $attachment[strtolower($obj->attribute)] = $obj->value; if (strtolower($obj->attribute) == "filename") { $attachment["is_attachment"] = true; $attachment["filename"] = $obj->value; } } } if ($part->ifparameters) { foreach ($part->parameters as $obj) { $attachment[strtolower($obj->attribute)] = $obj->value; if (strtolower($obj->attribute) == "name") { $attachment["is_attachment"] = true; $attachment["name"] = $obj->value; } } } $attachment["data"] = imap_fetchbody($this->conn, $msgNum, $prefix); // 3 is base64 if ($part->encoding == 3) { $attachment["data"] = base64_decode($attachment["data"]); } // 4 is quoted-printable elseif ($part->encoding == 4) { $attachment["data"] = quoted_printable_decode($attachment["data"]); } return($attachment); } }

The class’ constructor establishes a connection to a mail server. The option of using SSL encryption is also available if you have a certificate. The destructor closes the connection.

类的构造函数建立与邮件服务器的连接。 如果您有证书,也可以使用SSL加密选项。 析构函数关闭连接。

The listMessages() method returns an array containing a list of all messages currently in the inbox, or you can optionally request information for one specific message by providing a message ID as an argument. The list returned doesn’t contain the actual contents of the email, but rather the from address, to address, subject line, and date.

listMessages()方法返回一个数组,其中包含收件箱中当前所有消息的列表,或者您可以选择通过提供消息ID作为参数来请求一条特定消息的信息。 返回的列表不包含电子邮件的实际内容,而是发件人的地址,收件人,主题行和日期。

The deleteMessage() method marks a message for deletion. The message will not actually be deleted until the connection is closed with the appropriate flag, which is done in the class’ destructor.

deleteMessage()方法将消息标记为删除。 在使用适当的标志关闭连接之前,实际上不会删除该消息,这是在类的析构函数中完成的。

The parseHeaders() method uses regular expressions to parse the email headers which appear in the email as a single block of text, and returns the information as an array for easy access.

parseHeaders()方法使用正则表达式来解析出现在电子邮件中的电子邮件标题,它们是单个文本块,并将信息作为数组返回以方便访问。

The mimeToArray() method separates each MIME type found and returns the information as an array. If multiple MIME types are found, then it’s a good indication that there are attachments.

mimeToArray()方法将找到的每个MIME类型分开,并将信息作为数组返回。 如果找到了多个MIME类型,则表明存在附件。

The getParts() method extracts the different parts of the email such as the body and attachment information and returns the information as an array.

getParts()方法提取电子邮件的不同部分,例如正文和附件信息,然后以数组形式返回信息。

The fetchBody() method returns the body of an e-mail that has only one part, or no attachments.

fetchBody()方法返回仅包含一部分或没有附件的电子邮件正文。

The decodeParts() method takes the base64 or quoted-printable encoded attachment data, decodes it, and returns it so you can do something useful with it.

decodeParts()方法获取base64或带引号的可打印编码的附件数据,将其解码并返回,以便您可以对它进行一些有用的操作。

With this class, you can now connect to the server and retrieve a complete list of messages in the inbox as follows.

使用此类,您现在可以连接到服务器,并按如下所示在收件箱中检索消息的完整列表。

<?php require_once "POP3.php"; define("EMAIL_HOST", "pop.liberty2.say"); define("EMAIL_USER", "not@liberty2.say"); define("EMAIL_PASSWD", "********"); $pop3 = new POP3(EMAIL_HOST, EMAIL_USER, EMAIL_PASSWD); $msgList = $pop3->listMessages(); foreach ($msgList as $msg) { echo "<pre>" . print_r($msg, true) . "</pre>"; }

摘要 (Summary)

This brings us to the end of Part 1. So far you have a game-plan for building the application and ensuring that only the messages you send are published. You also have the database schema and a class that allows you to connect to a POP3 server and retrieve messages. Be sure to come back for Part 2 to see how these pieces fit together to realize the project.

这使我们进入第1部分的结尾。到目前为止,您已经有了一个构建应用程序并确保仅发布您发送的消息的游戏计划。 您还具有数据库架构和一个类,该类使您可以连接到POP3服务器并检索消息。 确保返回第2部分,以了解如何将这些部分组合在一起以实现该项目。

Image via Angela Waye / Shutterstock

图片来自Angela Waye / Shutterstock

翻译自: https://www.sitepoint.com/creating-a-mobile-photo-blog-part-1/

创建移动应用移动应用

最新回复(0)