PHP7-学习手册-一-

102 阅读1小时+

PHP7 学习手册(一)

原文:Learn PHP 7

协议:CC BY-NC-SA 4.0

一、PHP 7 简介

Electronic supplementary material The online version of this chapter (doi:10.​1007/​978-1-4842-1730-6_​1) contains supplementary material, which is available to authorized users.

"PHP is a popular universal scripting language, especially suitable for web development. Fast, flexible and practical PHP provides power for everything from your blog to the most popular websites in the world. — www . php . net

章节目标/学生学习成果

完成本章后,学生将能够:

  • 理解灯,WAMP 和 MAMP 之间的区别
  • 成功安装 LAMP、WAMP 或 MAMP 的版本
  • 搜索互联网以解决问题
  • 解释编程语言和脚本语言的区别
  • 创建一个没有错误的简单 PHP 程序

PHP 5.5+,PHP 7+和 PHP.NET

今天,PHP(超文本预处理器)是 web 应用开发中最流行的语言之一。该语言已经发展到允许程序员使用过程化和面向对象的编程技术快速开发结构良好的无错误程序。它提供了使用许多预先存在的代码库的能力,这些代码库要么是基本安装自带的,要么可以安装在 PHP 环境中。这为您提供了多种完成特定任务的方法。它比许多其他语言提供了更多的灵活性。额外的代码库可以很容易地添加到环境中,这是它受欢迎的众多驱动力之一。过程语言——过程编程语言包括可以从程序的主流程中调用的函数/方法。程序流程跳转到函数/方法,执行模块内的代码,然后返回到程序主流程中的下一条语句。一些过程语言包括一个在程序执行时自动调用的主函数/方法。面向对象的语言—面向对象的语言使用类和对象。类类似于蓝图。一个类描述了一个对象可以包含什么,包括属性/变量和函数/方法。一个对象是一个类的实例(就像一个从蓝图中创建的建筑)。面向对象的语言提供了多态性、封装和继承。通过在对象本身中包含所有相关的函数/方法和属性/变量,对象被自然地封装。多态性允许在面向对象的对象中使用重复的方法/函数名。但是,“签名”必须是不同的。“签名”是传入方法/函数的变量类型(数字和字符)和从方法/函数传出的信息类型的组合。例如,可以创建几个 add 方法—一个只接受整数(整数),一个只接受浮点数(带小数的数字),一个接受组合。程序将根据传递给方法/函数的内容来决定调用哪个方法/函数。面向对象编程中的继承允许一个对象从另一个对象继承属性/变量和函数/方法。该对象还可以重写那些继承的项。这类似于孩子从父母那里继承特征。面向对象的语言也可以是事件驱动的。事件驱动的程序将“休眠”直到事件发生。这类似于 ATM 机程序等待用户输入 ATM 卡。

PHP 是一种开源语言。因此,这种语言的每个版本都是使用使用它的个人——程序员自己——的输入创建的。随着时间的推移,这允许语言向用户驱动的方向发展。自 1995 年拉斯马斯·勒德尔夫作为个人主页工具(PHP)首次发布以来,这些版本已经在互联网上发布,并提供论坛,让用户能够提出建议,甚至提供代码更改和添加。今天 www.php.net 是 PHP 官方网站。

Open source language-open source programming language is developed by related groups. The community accepts input from programmers' partners to suggest upgrades and corrections. Several community members work together to make suggestions and make language changes. Open source languages are "free". Non-open source languages (such as Microsoft C#) are created and updated by companies or major organizations. Non-open source languages are usually not "free".

A978-1-4842-1730-6_1_Fig1_HTML.jpg

图 1-1。

PHP.NET (09/24/15)

www.php.net 主页提供了该语言每个最新版本的信息。它还提供了有关未来版本的信息、为这些版本计划的功能以及计划的发布日期。此外,还可以找到其他相关的 PHP 信息,包括主要 PHP 会议的链接和信息。

A978-1-4842-1730-6_1_Fig2_HTML.jpg

图 1-2。

Get involved (09/24/15)

如前所述,这个网站为用户提供了帮助语言未来发展的能力。用户可以参与测试 beta 版本,并报告错误或程序错误。访问者还可以查看与未来可能的版本开发相关的文档。这是在向公众发布重大公告之前发现未来增强功能或安全修复的好方法。

A978-1-4842-1730-6_1_Fig3_HTML.jpg

图 1-3。

Download page (09/24/15)

正如您可能已经猜到的,下载页面提供了轻松访问该语言最新版本的能力。然而,正如您将注意到的,只提供了语言本身。更常见的是,建议初级用户使用 WAMP (Windows、Apache、MySQL、PHP);LAMP (Linux,Apache,MySQL,PHP);或者 MAMP (Mac,Apache,MySQL,PHP)包进行初始安装。这些包(我们将在后面看到)允许同时安装多个产品。否则,您必须运行许多单独的安装,如果安装了不兼容的版本,这会变得复杂并且容易出错。WAMP/LAMP/MAMP——开源(免费)组合,包括 Apache Web Server、MySQL 和针对特定操作系统(Windows、Linux 和 Mac)的 PHP。这些包是开源的。该软件组合用于创建动态网站和网络应用。

A978-1-4842-1730-6_1_Fig4_HTML.jpg

图 1-4。

Documentation pages (09/24/15)

PHP 网站的一个更重要的页面是文档页面。该页面允许用户搜索语言本身的描述和功能。您也可以下载完整的文档。但是,由于这是一个“实时”网站,可能会发生变化,因此最好直接从网站上获取最新信息。

A978-1-4842-1730-6_1_Fig5_HTML.jpg

图 1-5。

The Manual (11/11/14)

通过从头开始点击每个链接,您可以像使用教科书一样使用手册。手册的每一部分所提供的有限的解释可能会导致初学者想要放弃编程,而将兴趣转向像网络这样可怕的东西!该手册确实为有经验的程序员提供了很好的指导,因为该语言的语法类似于其他语言,如 JavaScript、Perl 和 Java。

A978-1-4842-1730-6_1_Fig6_HTML.jpg

图 1-6。

Search (11/11/14)

在网站的任何页面上,用户都可以输入一个术语、一个表达式,甚至一个函数名来查找更多信息。当在搜索框中输入信息时,网页将在搜索框下方向用户提供一个或多个选项供用户选择。

一旦用户选择了一个选项(例如图 1-7 中所示的 echo),搜索结果将为用户提供所请求项目的一般描述、功能的任何输入或输出(参数)以及示例代码。

A978-1-4842-1730-6_1_Fig7_HTML.jpg

图 1-7。

Echo (11/11/14)

示例代码通过使用注释(在图 1-8 中用//和金色表示)在代码本身中解释了函数的用法。注释不是可执行代码。可执行代码用颜色编码,突出显示字符串(红色)、变量(蓝色)、关键字(绿色)和 PHP 开始和结束标记(蓝色)。颜色编码有助于提高代码的可读性。它还可以使创建程序时更容易发现语法错误。许多 PHP 编辑器都提供了类似的配色方案。

A978-1-4842-1730-6_1_Fig8_HTML.jpg

图 1-8。

Echo code (11/11/14)

PHP 5.6+和 PHP 7+

随着 PHP 7 环境的发布,发生了很大的改进。PHP 5.5+极大地提高了安全性。在本书中,我们将使用最新的 PHP 加密工具“password hash ”,而不是目前许多书使用的 MD5。在过去的几年中,MD5 已经被证明易受黑客攻击。

"PHP 7 is based on the PHPNG project (PHP Next-Gen), which is led by Zend and aims to speed up PHP applications. The performance improvement realized by PHP 7 is enormous! Their differences in real applications are between 25% and 70%, all of which are realized by upgrading PHP without changing any line of code! " — www . zend . com

PHP 7 还取代了致命错误,以前致命错误会导致程序崩溃,异常可以在程序内部处理。

如果您要从以前的 PHP 版本迁移到 PHP 7,请查看以下链接:

http://php.net/manual/en/migration70.php

本书示例中使用的代码与 PHP 7 兼容。大多数例子也兼容 PHP 5.5 和 PHP 5.6。

做它

Go to www.​php.​net. Search for information on the print and printf functions. How are these functions similar? How are they different?   How do you “join the team” and help with the creation of the next version of PHP? Hint: Go to the “Get Involved” section of www.php.net , select “Guide for Contributors,” and then find the “Join the team” link. Of course, the web site changes, so you may need to find a different route to the information.   Which ways can the www.php.net web site be useful for a beginning PHP programmer?   What language is used to create PHP? Hint: The answer is somewhere on the www.php.net web site.   Go to www.php.net . Search for the list of improvements and changes with PHP 7. List those improvements and changes. Which of these do you think will affect a beginning level programmer?  

PHP、JavaScript、CSS、HTML 和 Apache Web 服务器

PHP 是一种脚本语言。脚本语言不同于实际的编程语言。编程语言(如 Java)是由程序员用类似英语的语法编写的。程序被编译,这意味着它从英语语法转换成机器代码(0 和 1)。该代码然后在兼容的操作系统和硬件中执行(运行)。脚本语言不使用编译器。第一次访问代码时,会在程序执行时逐行解释。

您可能想知道这是否会导致代码比编译后的代码慢。答案是否定的。一旦代码被执行了一次,被解释的代码就留在计算机或服务器的内存中,供其他执行使用。如果程序员修改了这段代码,新的版本将替换内存中的前一个版本。

JavaScript 也是一种脚本语言。您可能知道,通过查看源代码,可以在 web 浏览器中看到 JavaScript 代码,如图 1-9 所示。

A978-1-4842-1730-6_1_Fig9_HTML.jpg

图 1-9。

JavaScript, HTML, and CSS code from yahoo.com (11/11/14)

图 1-9 中显示的源代码来自 www.yahoo.com ,它显示了几种语言的组合,包括 HTML、CSS 和 JavaScript。JavaScript 代码(以黑色显示)位于脚本标签(<script type="text/JavaScript"></script>之间。如果您的浏览器允许 cookie,这段 JavaScript 代码将尝试在您的机器上创建一个 cookie。

然而,当我们查看 www.php.net 源代码时(图 1-10 ,我们看不到任何 PHP 脚本代码。这里有一些 PHP 文件的链接,但是没有显示实际的 PHP 代码。为什么?

A978-1-4842-1730-6_1_Fig10_HTML.jpg

图 1-10。

The www.php.net source code (11/11/14)

JavaScript 代码驻留在用户的计算机上。它在浏览器中被解释和执行。PHP 代码驻留在 web 服务器上。代码也可以被解释和执行,但是是由 web 服务器,而不是浏览器。执行 PHP 代码的结果被返回给浏览器,而不是实际的代码本身。

<?php

Print "Hello";

?>

Note

您可能会注意到使用 PHP 的其他格式(例如:<%<%=%><script language="php">);在 PHP 7 中,这些样式不再有效。以前实际上已经折旧了,但是仍然可以使用。

您可能会猜测这段代码会显示Hello。虽然这是正确的,但问题是,产生这种结果的过程是什么?

如果这段代码放在 web 服务器上的一个文件中(如hello.php),我们将使用我们的 web 浏览器通过在 URL(地址)框中输入它的名称和位置来请求这个文件(如 http://servera.com/hello.php )。输入的地址指示浏览器向 web 服务器(servera.com)发送 HTTP Get请求,以返回网页(hello.php)。

A978-1-4842-1730-6_1_Fig11_HTML.jpg

图 1-11。

Requesting an HTML/JavaScript web page

接收请求的 web 服务器将确定 PHP 代码必须首先被解释和执行。它只是通过查看所请求文件的文件扩展名(.php)来确定这一点。文件中的任何 PHP 代码都会被发送到 PHP 处理器进行解释和执行。代码的执行结果被返回给 web 服务器,web 服务器又将它(以及任何其他 HTML 和/或 JavaScript 代码)发送回浏览器。在本例中,浏览器将返回并显示Hello。如果我们接着查看源代码,如上所述,我们只会看到真正的单词Hello。我们不会看到任何 HTML 或 PHP。为什么呢?因为我们没有向浏览器发回任何 HTML。

A978-1-4842-1730-6_1_Fig12_HTML.jpg

图 1-12。

Requesting a web page with PHP code

您可能想知道是否可以使用这个过程发送回实际的 HTML(和/或 JavaScript)代码来创建动态 web 页面。答案是肯定的。PHP print函数将返回放置在""之间的任何 HTML(或 JavaScript)代码。浏览器将解释 web 服务器返回的任何代码。

Print function. Print function is not actually a function. It is a linguistic structure. The function string is required to be enclosed in quotation marks when passing. Structure does not need to enclose strings in quotation marks. Still recommended. Print will pass the content passed to it to the browser. It will try to convert any item that is not a string into a string (text) format, because all items displayed in the web page are in text format. For more information, visit: http :// php . net / manual / en / function . . php Please visit the free "New Boston" (thenewboston . com) video (s) at https :// www . thenewboston . com / videos . .

Note

本书提供的所有链接均可从 http://www.littleoceanwaves.com/securephp 进入。

<?php

Print "<h1>Hello</h1>";

?>

如果我们将代码更改为上面的清单,浏览器会将Hello显示为 HTML 标题(h1)。使用print函数的缺点是程序无法控制语句在网页上的显示位置。该语句实际上将显示为代码的第一行,甚至在任何其他现有的 HTML 标记之前。如果我们只是向用户返回一个语句,比如“您的过程已经完成”,这可能没问题。但是,如果您的目标是在页面上的精确位置格式化输出,这可能是不可接受的。我们可以选择其他技术和功能来消除这个问题。但是,这超出了我们目前的讨论范围。

现在我们知道我们必须在 web 服务器的帮助下解释和执行 PHP 代码,那么我们应该使用什么服务器呢?

Apache web 服务器是最常用于托管和处理 PHP 网页请求的服务器。像其他 web 服务器一样,Apache 也可以接受和返回对其他类型文件的请求,包括 HTML、JavaScript、PERL、图像和 RSS 提要。如前所述,Apache 通过首先查看所请求文件的文件扩展名来确定 HTTP 请求需要完成哪些进程。

A978-1-4842-1730-6_1_Fig13_HTML.jpg

图 1-13。

Apache.org web site (09/24/15)

Apache 和 PHP 一样,都是开源产品。Apache web 服务器的所有更改都由 Apache 软件基金会协调。ASP 维护着apache.org网站,为用户和开发人员提供发现当前正在开发的项目的能力,以及下载最新版本的 Apache 的能力。然而,如前所述,下载 PHP、Apache 和 MySQL 的不同版本会导致版本不兼容的问题。除非你知道自己在做什么,否则下载完整的 WAMP、LAMP 或 MAMP 版本要明智得多。

A978-1-4842-1730-6_1_Fig14_HTML.jpg

图 1-14。

Apache’s Get Involved (09/24/15)

Apache 软件基金会还鼓励他们产品的所有用户保持更新,并参与未来产品的开发。我们鼓励用户加入讨论和邮件组,测试新版本,甚至帮助修复 bug 或为他们的产品添加新功能。

做它

What are the differences in executing PHP code compared to executing Java code?   What is the difference between a scripting language and a programming language? What type of language is PHP?   How does the Apache web server handle requests for a PHP web page?   Why can we see JavaScript code within a web browser but we can’t see PHP code?   Go to www.apache.org . What are some of the ways that you can become involved with the development of Apache projects, even though you have limited experience?  

PHP、Apache 和 MySQL

当网页向数据库请求信息时会发生什么?

通常,数据库存储在独立于 web 服务器本身的服务器上。

对数据的请求是来自 web 服务器还是来自 PHP 处理器?

由于 SQL 语句包含在 PHP 代码本身中,PHP 处理器将 SQL 语句发送到数据库管理系统(MySQL)进行处理。SQL—结构化查询语言是一种特殊的语言,用于更新、插入或删除 DBMS(数据库管理系统)中的数据。DBMS 是一种应用,它与程序语言和数据库进行交互,以更新、插入或删除数据。DBMS 使用 SQL 来解释数据库中数据所需的更改。有关 SQL 的更多信息,请访问http``://``en``.``wikipedia``.``org``/``wiki``/``SQL.

A978-1-4842-1730-6_1_Fig15_HTML.jpg

图 1-15。

Requesting a PHP web page that retrieves information from a MySQL database

Apache 服务器将首先发现 PHP 代码必须被解释。PHP 代码将被发送到 PHP 处理器。PHP 处理器解释代码(一行一行)。在这样做的时候,它会发现 SQL 语句必须针对数据库执行。然后,SQL 语句被传输到适当的数据库管理系统(DBMS)进行处理。DBMS 将把 SQL 语句的执行结果返回给 PHP 处理器。然后,PHP 处理器将使用这些结果来格式化输出,以提供给 Apache 服务器。然后,Apache 服务器将把 PHP 处理器返回的结果与可能驻留在原始请求页面上的任何其他 HTML(和/或 JavaScript)代码结合起来,并将所有输出返回给用户机器上的浏览器。然后,浏览器将解释 HTML 和 JavaScript 来显示所请求页面的结果。

你全都明白了吗?

让我们看一个“真实世界”的例子,如图 1-16 所示。

A978-1-4842-1730-6_1_Fig16_HTML.jpg

图 1-16。

Google.com search for “green cats” (11/12/14)

出于一些非常奇怪的原因,我们决定在互联网上查找“绿猫”。当我们将字符串输入到我们最喜欢的搜索引擎(本例中是 Google)中,然后单击 search 按钮,信息就会被传递到某个 Google 服务器群。哪里?

谁知道;它可能在地球上的任何地方。但互联网的强大之处在于,只要能快速拿回结果,我们就不在乎。

A978-1-4842-1730-6_1_Fig17_HTML.jpg

图 1-17。

Green cats (11/12/14)

好吧,我必须说我很惊讶有 1.04 亿个可能和绿猫有关的链接。哇哦。也许我们应该过滤掉一些。然而,关键是 Google 返回一个网页,上面有链接列表和对这些链接的描述(外加广告)。

Google 是否返回了一个已经存在的静态页面?

没有。服务器根据用户的请求创建了一个动态页面。谷歌算法(软件)搜索巨大的谷歌数据库农场。该请求首先从用户的浏览器发送到 Google web 服务器。然后,web 服务器向 Google 数据库发送请求(实际上使用了一种类似于 SQL 的 Google 查询语言)以返回关于“绿猫”的信息。web 服务器上的软件然后编译结果,添加 HTML 和 JavaScript(还有一些 Google Script 语言代码)来格式化结果网页,并将信息返回给用户。

Static and dynamic web pages-static web pages will not change due to user requests or inputs. This page is created by a web developer and resides on a web server. When a user requests a page through a browser, a copy of the page is sent to the browser for display. There is no dynamic page in the web server. Use input from users to create pages. The program residing on the web server will create and format the page. The page created by the program is then downloaded to the user's browser. A copy of the web page (usually) is not saved on the web server. For more information about static web pages, please visit http :// en . wikipedia . org / wiki / Static _ _ page For more dynamic webpage information, please visit: [http :// en . wikipedia . org / wiki / Dynamic _ web _ en.wikipedia.org/wiki/Dynamic_web_page

每个页面都被下载到用户的网络浏览器了吗?

不,只是第一页。第一个结果页面底部的页面链接向 web 服务器返回信息,请求下一组信息(以动态创建第二个页面或另一个请求的页面)。正如您现在可能开始发现的,我们刚刚讨论的与处理互联网上的 PHP 文件相关的相同过程是创建动态页面的一个非常常见的过程。

您可能已经注意到显示的结果页面 URL 地址有一些有趣的地方。现在的地址是 https://www.google.com/?gws_rd=ssl#q=Green+Cats ,而不是 www.google.com 。Google 算法在向服务器发送搜索请求时使用 GET HTTP 请求。

HTTP—-Hypertext Transfer Protocol is a protocol (standard) for transmitting messages (text and web pages) between nodes (computers and servers) on the Internet. This is a request-response protocol. For example, the user "requests" a web page through the browser. The web server "responds" to the request and returns the page to the browser. Convert the browser request into an HTTP Get request (such as GET / pages / mypage . html HTTP / . 1) and send it to the web server. The web server responds with the requested information and status code (such as http / 1 . 1 200 OK). For more information about HTTP, please visit http :// en . wikipedia . org / wiki / Hypertext _ Transfer _ Protocol Protocol

<form name="orders" method="get" id="orders" action="searchprocess.php">

Name: <input type="text" name="customername" id="customername"><br />

<input type="submit" value="Submit your name">

</form>

让我们看一个简单的例子来发现发生了什么。假设上面的代码保存在本地主机网站上的projects文件夹下的index.html文件中。

A978-1-4842-1730-6_1_Fig18_HTML.jpg

图 1-18。

Index.html example

如果用户在浏览器显示的文本框中输入Fred,结果页面(通过在 web 服务器上解释并执行searchprocess.php文件并将结果发送回浏览器而创建)将显示 URL 行: http://127.0.0.1/projects/searchprocess.php?customername=Fred

A978-1-4842-1730-6_1_Fig19_HTML.jpg

图 1-19。

Execution of searchprocess.php

文本框的名称(customername)和文本框中输入的值(Fred)现在在 URL 行上可见。实际上,customername现在是一个参数,Fred现在是参数的值。这是使用 GET 进程的结果。

当我们单击 Google Search 按钮或简单示例中的 Search 按钮时,请求的信息通过 GET HTTP 进程发送。接收程序所需的所有信息(和变量)都在实际的 URL 行上发送,由处理初始请求的 web 服务器上的程序接收。

为什么谷歌搜索引擎通过 GET 而不是 POST 发送信息(这样会隐藏信息)?

主要原因是为了节省服务器内存。想想谷歌对信息的数百万次请求。如果所有这些请求都驻留在内存中,服务器很快就会崩溃。此外,由于用户是在“公开”搜索信息,因此没有理由隐藏信息。在后面的章节中,我们将发现如何在 PHP 程序中读取 GET 和 POST 参数。

然而,现在让我们回到我们对 Apache、PHP 和 DBMS 的讨论。

PHP 可以从许多类型的 DBMS 系统中访问信息,包括 Oracle 和 SQL Server。然而,最流行的组合(如前所述)是将 PHP 与 MySQL 配对。我敢打赌,在这一点上,你能猜到为什么?是的,它是开源和免费的。MySQL 也是比较容易使用的 DBMS 系统之一。

A978-1-4842-1730-6_1_Fig20_HTML.jpg

图 1-20。

www.​mysql.​com (09/24/15)

就像我们讨论过的所有开源产品一样,用户可以去官方网站( www.mysql.com )下载最新版本。此外,正如您可能猜到的,您可以加入帮助开发 MySQL 新版本和相关产品的乐趣。可以下载当前版本和几个以前版本的文档。文档内容相当丰富,不适合智力低下的人或初学者。另外,由于你可能已经厌倦了阅读,所以不建议你单独下载 MySQL 的新版本,直到你有了更多的经验。坚持 WAMP,灯,MAMP 套餐,至少现在是这样。

做它

Why does the PHP processor send SQL to the DBMS instead of the Apache web server sending it directly to the DBMS?   What might Apache do with the information received from the DBMS before sending it back to the user’s browser?   Go to www.mysql.com . What is the latest version of MySQL? Which versions of Apache and PHP are compatible?   Why do search engines pass information via GET HTTP requests instead of POST HTTP requests? When would you use a POST request?  

把它们放在一起——PHP、Apache 和 MySQL

到目前为止,您可能已经发现,PHP、Apache 和 MySQL 需要无缝地一起运行,才能成功地创建动态网页。有许多开发包提供了这些产品的组合,以及其他工具,如 PhpMyAdmin(这对设置 web 服务器和数据库有很大的帮助)。通过安装这些产品中的一个,你将大大降低你的沮丧程度,甚至可能设法保留你的大部分头发。我们将简要地看两个最流行的;EasyPHP 和 XAMPP。出于两个原因,我们不会深入探讨或提供分步安装指导。一旦这本书出版,方向可能会改变,使用默认设置是没问题的。大多数时候,接受开发人员的建议是可行的。

EasyPHP

A978-1-4842-1730-6_1_Fig21_HTML.jpg

图 1-21。

www.​easyphp.​org (09/24/15)

你可以从下面的链接下载 EasyPHP 的开发者版本。没有必要下载主机版本,除非您计划将“实时”网页直接从您的计算机托管到互联网上。

http://www.easyphp.org/easyphp-devserver.php

开发者版本的 EasyPHP 是一个 WAMP (Windows,Apache,MySQL,PHP)包,用于微软的 Windows 环境中。您还可以选择安装其他工具来帮助开发。然而,对于我们的目的,您只需要基本安装。安装后,这些文件将位于 EasyPHP 目录下的 program files 目录中。

Warning

下载时请注意您点击了网站上的哪些按钮。如果您在单击按钮之前没有阅读您正在下载的内容,您可能会下载您不感兴趣的额外项目。

单击网站上的下载箭头下载安装程序后,按照软件提供的说明进行操作。第一次尝试时,保留所有默认设置。希望一切都能正确安装。如果没有,请阅读下一节“常见安装问题”。

常见安装问题
缺少 C#库

PHP 7(以及 PHP 的早期版本)需要 Microsoft Visual Studio C#库。如果您使用的是 Windows 8 或更高版本,可能已经安装了该库。此外,如果您有最新版本的 Microsoft Visual Studio,它也可能已经安装。如果您收到一条错误消息,指出 C#丢失或版本错误,请将该消息粘贴到 Internet 上的搜索引擎中。搜索 Microsoft 的响应以获得修复错误的指导。响应应包括下载缺失文件和安装说明的链接。

端口冲突

如果您已经有一个使用端口 80 的服务,端口 80 是您的 PC 和外部世界之间的 HTML 流量的默认端口,当它试图运行时,您将收到来自 Apache 的错误消息。您可以通过多种方式解决这个问题。

Wikipedia defines ports as: in computer networks, ports are application-specific or process-specific software structures that are used as communication endpoints in computer host operating systems. The purpose of port is to uniquely identify different applications or processes running on a single computer, so that they can share a single physical connection to a packet-switched network like the Internet. In the context of Internet protocol, a port is associated with the IP address of the host and the type of protocol used for communication. For more information about ports, please visit: [http :// en . wikipedia . org / wiki / Port _( _ networking](en.wikipedia.org/wiki/Port_(…

A.如果您不介意在开发时关闭使用该端口的其他服务,您可以遵循下面的说明。一旦你使用完 Apache 和 PHP,你可以重新打开服务或者重启你的电脑,服务就会重新打开。

Go to the Microsoft Windows 7/8/10 Task Manager (press Ctrl+Alt+Delete at the same time).   Select the Services tab.   Look for any of the following services in Windows 7/8/10. If you find one running, right-click it and turn it off. Then try restarting Apache again. If that does not work, turn that one back on and try another one. (The names may be slightly different depending on the version of Windows.)  

SQL Server Reporter、Web 部署代理、BranchCache、同步共享服务、WAS (IIS 管理员)和 W3SVC

B.如果您需要运行其他服务,或者您没有关闭端口 80 上的服务的管理权限,您可以更改 Apache 的默认监听端口位置。

转到系统托盘(屏幕右下角)。通过滚动图标找到 EasyPHP 图标。应该会出现每个的描述。如果看不到图标,请单击系统托盘中的向上箭头以查看更多图标。右键单击 EasyPHP 图标。选择配置,然后选择 Apache。这将在记事本(或您的默认文本编辑器)中打开 Apache 配置文件(httpd.conf)。首先在某个地方保存这个文件的副本,以防出错。这将让你从任何重大错误中恢复过来。然后在文件中搜索Listen 127.0.0.1:80。仅在该行上将80的出现改为808081;。这将允许 Apache 服务器监听一个不常用的端口。重新保存文件(确保将原始文件重新保存到原始位置)。

Note

确保在使用记事本或任何其他文本编辑器时使用“另存为”,然后选择“所有文件”作为文件类型。还要确保包含文件扩展名.conf。如果您不将文件类型更改为所有文件,您的文件将被保存为httpd.conf.txt。如果发生这种情况,服务器将看不到该文件。您可以通过重新打开文件并以正确的方法保存它来轻松解决这个问题。

然后,您可以通过返回系统托盘找到 EasyPHP 图标来重新启动 Apache。双击图标;将出现一个消息框,显示 Apache 和 MySQL 的状态。对于 Apache 状态,您可能会看到红色。单击 Apache 按钮。几分钟后,它应该会变成绿色。这将表明服务器现在正在运行。对 MySQL 做同样的事情。

丢失的文件

如果您收到一条与此相关的错误消息,不知何故,您的文件在安装前已经损坏。返回 EasyPHP 网站,再次下载文件。此外,如果您不知何故弄乱了 Apache 配置文件,请返回并重新安装产品。

无法在程序文件目录中安装文件

这表明您或其他人对该目录有很高的安全性限制。重新运行安装,并将安装位置更改为另一个目录。请记住,当我们在本书后面引用程序文件目录时,您应该查看文件的安装目录。

Apache 延迟和挂起

在 Windows 8/10 中,您可能会遇到 Apache 运行缓慢或挂起的问题。要纠正这个问题,请转到系统托盘(屏幕右下角)。通过滚动图标找到 EasyPHP 图标。应该会出现每个的描述。如果看不到图标,请单击系统托盘中的向上箭头以查看更多图标。右键单击 EasyPHP 图标。选择配置,然后选择 Apache。这将在记事本(或您的默认文本编辑器)中打开 Apache 配置文件(httpd.conf)。首先在某个地方保存这个文件的副本,以防出错。这将让你从任何重大错误中恢复过来。然后将下面两行添加到文件的底部。

接受过滤器 http 无

AcceptFilter https none 重新保存文件(确保将原始文件重新保存到原始位置)。

其他错误

对于这里没有讨论的错误,将错误复制并粘贴到搜索引擎中。找到一个回答专栏或博客,提供修复错误的建议。网上有很多免费资源。不要花钱请网站(或其他人)来解决你的问题。

配置

您需要确定希望 Apache 何时运行。Apache 可以设置为在您启动 PC 时、应用需要时运行,或者手动运行。要更改设置,您可以右键单击系统托盘(屏幕右下角)中的 EasyPHP 图标,然后选择配置,然后选择 EasyPHP。如果看不到图标,请点按系统托盘中的向上箭头。应该会出现一个小屏幕,允许您选中(或取消选中)两个选项—在会话启动时启动和在应用启动时启动服务器。

有许多可选的库,您可以根据需要链接或取消链接到 PHP。在许多情况下,库已经被加载,只需要被链接。您可以通过转到 PHP 配置文件(php.ini)并删除行首的注释(;)字符来添加这些库。右键单击系统托盘中的 EasyPHP 图标可以很容易地找到 PHP 配置文件。然后选择配置和 PHP。此时没有必要进行任何更改。还建议您仅在需要时进行这些更改。可以使用 Curl 和本书后面章节讨论的其他方法添加其他库。

要更深入地了解php.ini文件,请在https://www.thenewboston.com/videos.php?cat=11&video=16993观看免费的“新波士顿”(thenewboston.com)视频。

XAMPP(洗发精)

A978-1-4842-1730-6_1_Fig22_HTML.jpg

图 1-22。

XAMPP at www.​apachefriends.​org (09/24/15)

虽然 XAMPP 与 EasyPHP 相似,但 XAMPP 更受欢迎,因为它有免费的 Windows、Linux 和 OS X 版本。它还包括许多附加组件,包括一些最流行的内容管理系统——Drupal、Joomla 和 WordPress。可以在 XAMPP 官方网站或许多其他下载位置直接获得最新下载。

https://www.apachefriends.org/

Warning

注意你在网站上点击的按钮。如果您在单击按钮之前没有阅读您正在下载的内容,您可能会下载您不感兴趣的额外项目。

在您第一次尝试安装时,请使用开发人员在安装软件中建议的默认设置。你将大大减少出现问题或头痛的可能性。如果确实有错误,请阅读下一节“常见安装问题”以获得帮助。

常见安装问题
端口冲突

如果您已经有一个使用端口 80 的服务,端口 80 是您的 PC 和外部世界之间的 HTML 流量的默认端口,当它试图运行时,您将收到来自 Apache 的错误消息。您可以通过多种方式解决这个问题。

A.如果您不介意在开发时关闭使用该端口的其他服务,您可以按照视频链接上的说明进行操作。一旦你使用完 Apache 和 PHP,你可以重新打开服务或者重启你的电脑,服务就会重新打开。

Go to the Windows 7/8/10 Task Manager (press Ctrl+Alt+Delete at the same time).   Select the Services tab.   Look for any of the following services in Windows 7/8/10. If you find one running, right-click it and turn it off. Then try restarting Apache again. If that does not work, turn that one back on and try another one. (The names may be slightly different depending on the version of Windows.) SQL Server Reporter, Web Deployment Agent, BranchCache, Sync Share Service, WAS (IIS Administrator), and W3SVC  

B.如果您需要运行其他服务,或者您没有关闭端口 80 上的服务的管理权限,您可以更改 Apache 的默认监听端口位置。

转到系统托盘(在 Microsoft Windows 中,它位于屏幕的右下角)。通过在图标上滚动鼠标找到 XAMPP 图标。应该会出现每个的描述。如果看不到图标,请单击系统托盘中的向上箭头以查看更多图标。双击该图标。应该会出现控制面板。您应该会在控制台上看到红色的启动错误消息。如果是端口冲突,单击 Apache 右侧的 Config 按钮。从提供的列表中选择httpd.conf。这将在记事本(或您的默认文本编辑器)中打开 Apache 配置文件(httpd.conf)。首先在某个地方保存这个文件的副本,以防你出错。这将允许您恢复原始文件。在文件中搜索 Listen 80。将80的发生更改为808081。这将允许 Apache 服务器监听其中一个不常用的端口。重新保存文件(确保将原始文件重新保存到原始位置)。

Note

确保在使用记事本或任何其他文本编辑器时使用另存为,然后选择所有文件作为文件类型。还要确保包含文件扩展名.conf。如果您不将文件类型更改为所有文件,您的文件将被保存为httpd.conf.txt。如果发生这种情况,服务器将看不到该文件。您可以通过重新打开文件并以正确的方法保存它来轻松解决这个问题。

然后,您可以通过在 XAMPP 控制台中单击 Apache 旁边的 start 按钮来重新启动 Apache。如果 Apache 的状态为绿色,那么您还需要通过单击 MySQL 右侧的 start 按钮来启动 MySQL。

丢失的文件

如果您收到一条与此相关的错误消息,不知何故,您的文件在安装前已经损坏。返回 XAMPP 网站,再次下载文件。如果您不知何故弄乱了 Apache 配置文件,您还需要再次下载这些文件。

无法在程序文件目录中安装文件

这表明您或其他人对该目录有很高的安全性限制。重新运行安装,并将安装位置更改为另一个目录。请记住,当您在本书后面引用程序文件目录时,您应该查看文件的安装目录。

Apache 延迟和挂起

在 Windows 8/10 中,您可能会遇到 Apache 运行缓慢或挂起的问题。要纠正这个问题,请转到系统托盘(屏幕右下角)。通过滚动图标找到 XAMPP 图标。应该会出现每个的描述。如果看不到图标,请单击系统托盘中的向上箭头以查看更多图标。右键单击 XAMPP 图标。选择配置,然后选择 Apache。这将在记事本(或您的默认文本编辑器)中打开 Apache 配置文件(httpd.conf)。首先在某个地方保存这个文件的副本,以防出错。这将让你从任何重大错误中恢复过来。然后将下面两行添加到文件的底部。

接受过滤器 http 无

AcceptFilter https none

重新保存文件(确保将原始文件重新保存到原始位置)。

其他错误

对于这里没有讨论的错误,将错误复制并粘贴到搜索引擎中。找到一个回答专栏或博客,提供修复错误的建议。网上有很多免费资源。不要花钱请网站(或其他人)来解决你的问题。

配置

您可以转到控制面板来更改 XAMPP 的配置(双击屏幕右下角系统托盘上的 XAMPP)。然后单击屏幕右上角的配置按钮(不是应用右侧的配置按钮)。然后,您可以选中(或取消选中)那些希望在下次控制面板启动时自动启动的应用。你应该在 Apache 和 MySQL 中查找这本书的内容。当然,你可以在需要的时候从控制面板启动它们。

有许多可选的库,您可以根据需要链接或取消链接到 PHP。在许多情况下,库已经被加载,只需要被链接。您可以添加这些库,方法是转到 PHP 配置文件(php.ini)并删除行首的注释(;)字符。双击系统托盘中的 XAMPP 图标可以很容易地找到 PHP 配置文件。然后单击 Apache 右侧的 Config 按钮。将显示一个列表;选择php.ini。此时没有必要进行任何更改。还建议您仅在需要时进行这些更改。可以使用 Curl 和本书后面章节讨论的其他方法添加其他库。

微软互联网信息服务器

或者,如果您无法让 Apache 在 Windows(尤其是 Windows 8 或 Windows 10)中正常运行,或者您喜欢微软的 IIS 服务器,您可以安装 PHP 来使用微软 IIS(互联网信息服务器)而不是 Apache。有关更多信息,请访问:

http://www.microsoft.com/web/platform/phponwindows.aspx

做它

Use a search engine to answer this question: You receive the following error either while installing or as soon as you try to start XAMMP or EasyPHP. How can you find the solution to your problem? What might be causing this error? Internal Server Error The server encountered an internal error or misconfiguration and was unable to complete your request. Please contact the server administrator, you@example.com and inform them of the time the error occurred, and anything you might have done that may have caused the error. More information about this error may be available in the server error log.   Use a search engine to answer this question: What is XAMPP error #1130? How can you fix this error?   Use a search engine to answer this question: When trying to run a PHP program using EasyPHP (and Apache) you receive the error below. What is causing this error? How can you fix it? Cannot load mcrypt extension. Please check your PHP configuration.   If you have not already attempted to do so, install either EasyPHP or XAMPP on your personal machine. Did you have any problems with your installation? If so, what problems did you have? How did you solve those problems?  

测试您的环境

你现在有绿灯了,对吧?一切正常吗?

希望如此。然而,你需要确保。最好的方法是测试您的环境。

测试您的管理环境

首先,我们需要测试服务器,看看我们的管理页面是否会显示。在 EasyPHP 中,您可以执行以下任一操作:

1.右键单击 EasyPHP 图标并选择管理。

或者

2.打开您最喜欢的浏览器,输入以下内容:

http://127.0.0.1/home/

如果由于冲突而不得不更改您的端口,您可能需要输入端口号,例如:

http://127.0.0.1:8080/home/

您应该会看到一个类似于图 1-23 所示的屏幕。

A978-1-4842-1730-6_1_Fig23_HTML.jpg

图 1-23。

EasyPHP administration screen (PHP 5.6)

对于 XAMPP,打开您最喜欢的浏览器,输入以下地址:

http://127.0.0.1/dashboard/

如果由于冲突而不得不更改您的端口,那么您还必须包括此端口:

http://127.0.0.1:8080/dashboard/

如果 XAMPP 安装正确,您应该会看到类似于图 1-24 所示的屏幕。

A978-1-4842-1730-6_1_Fig24_HTML.jpg

图 1-24。

XAMPP dashboard screen (09/24/15)

如果此时你看不到这个页面(或显示 XAMPP 的某个页面),那一定是出了问题。检查以下内容:

是 EasyPHP 还是 XAMPP 在运行(启动)?你在 XAMPP 控制面板或 EasyPHP 中看到 Apache 的绿灯或绿色阴影了吗?如果没有,请尝试单击开始按钮或链接。

如果 Apache 无法启动,您会看到错误信息吗?如果没有,请检查错误日志文件。对于 EasyPHP,右键单击系统托盘上的图标,并选择 Apache 的错误日志文件。对于 XAMPP,单击 Apache 旁边的控制面板上的日志按钮,并选择错误日志。

如果您看到绿色并且页面似乎被锁定,请尝试停止并重新启动 Apache。可能要试几次才能唤醒它。如果它继续挂起,请检查您的计算机设置。您是否最大限度地利用了 CPU?

你能确定问题吗?如果你有一个错误信息,把它粘贴到你最喜欢的搜索引擎中,看看专家对这个问题怎么说。

做它

1.如果您还没有这样做,请按照上面的说明测试您的环境。你有什么问题吗?如果是,发生了什么问题?你是如何解决这些问题的?

测试您的 PHP 环境

希望此时一切都好。要么你运气一直很好,要么你设法解决了你遇到的所有问题。然而,你仍然需要看看你是否能在 Apache 中运行你自己的 PHP 程序。

打开一个文本编辑器(不是 Word,但是 Notepad 或 Notepad++都可以),按照显示的内容输入下面的代码。

<?php

print "Hello World";

?>

A978-1-4842-1730-6_1_Fig25_HTML.jpg

图 1-25。

Using Save As with All Files to save PHP programs

使用文件菜单上的另存为选项,将文件类型更改为所有文件或php。输入文件名myfirstprogram.php并将其保存在以下位置之一。

如果您使用的是 EasyPHP,请将其保存到:

C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\data\localweb\projects

当然,您应该将版本名称(或程序文件名)更改为您在计算机上使用的正确版本(位置)。如果您的 EasyPHP 版本没有 localweb\projects 文件夹,请在 EasyPHP 文件夹下找到www文件夹的位置,并创建一个名为projects的文件夹。然后将文件保存在该文件夹下。

如果你正在使用 XAMPP,首先转到C:\xampp\htdocs并创建一个名为projects的文件夹。然后回到你的文本编辑器,选择另存为(不要忘记将文件类型改为所有文件或php),将文件命名为myfirstprogram.php并保存到下面的位置。

C:\xampp\htdocs\projects

如果你在 EasyPHP 或 XAMPP 位置正确地保存了你的文件,你可以通过在你的浏览器 URL 框中输入以下内容来运行你的程序。

http://127.0.0.1/projects/myfirstprogram.php

如果您更改了端口,则将第一部分更改为 http://127.0.0.1:8080/ (输入您正在使用的正确端口来代替8080)。

你的程序应该显示如图 1-26 所示的信息。

A978-1-4842-1730-6_1_Fig26_HTML.jpg

图 1-26。

Hello World

常见问题

不显示任何内容,错误 404:

Make sure you typed the address exactly as shown.   Your server might be hung up. Stop and restart it.   Make sure you placed your file in the correct location.   Make sure you saved your file as a .php file and not as .txt. Try Save As again and renaming the file (make sure file type is either All Files or php).   Check for typos in your actual program code. Did you remember the semicolon (;)? Fix any and resave. You might need to stop and start the server if it does not see the changes for some reason. You can go to the log files and look at the PHP log files to see any errors that might exist in your code.   Go to the Apache log files (see directions in previous common problems) to look for errors. If you cannot correct them, copy the errors and paste them in a search engine to see what others have found as solutions.  

显示的是实际的程序代码,而不是执行代码的结果:

Make sure you saved your file as a .php file and not as .txt. Try Save As again and renaming the file (make sure file type is either All Files or php).   Your Apache server or PHP might not be started or is hung. Stop and start Apache again.   Did you forget or have a typo in the <?php or ?> lines?   Go to the Apache log files (see directions in previous common problems) to find the errors. If you cannot correct them, copy the errors and paste them in a search engine to see what others have found as solutions.  

对于任何其他错误,将它们复制并粘贴到网络搜索引擎中,看看其他人发现了什么解决方案。

EasyPHP 的代码教室

如果你在电脑上安装 LAMP、MAMP 或 WAMP 软件时仍然有问题,一切都还没完。

EasyPHP ( www.easyphp.org )现在为学生和教师提供了一个在线编码环境。这个环境(见图 1-27 )允许你输入代码(下面的黑色窗口),点击提交按钮(红色按钮),并在右边看到你的结果(白色窗口)。

A978-1-4842-1730-6_1_Fig27_HTML.jpg

图 1-27。

www.​codeclassroom.​net

做它

1.如果您尚未测试您的环境,请进行测试。测试成功了吗?你遇到过什么问题,如果有的话?你是如何解决那些问题的?

别名目录

在现实世界中,在 web 服务器中创建别名目录是常见的做法。别名目录是文件的“虚假”位置,它欺骗网站的用户,使他们相信文件在一个位置,而它在另一个位置。

为什么要使用别名目录?随着网站的增长,文件在服务器上的位置可能必须改变。通过使用别名,网站的用户不会知道文件的实际位置已经改变。别名使您能够将文件存储在计算机(服务器)上的任何位置。如果不使用别名,所有文件都必须存储在默认位置。默认位置是:

easy PHP:

xampp:

您可能需要考虑创建一个别名目录,尤其是当您希望将文件放在一个跳转驱动器上时。在本书中,我们假设文件位于默认位置下的一个projects文件夹中。

easy PHP:

xampp

这将允许我们使用相同的 URL 测试程序,不管我们是使用 EasyPHP 还是 XAMPP。

http://127.0.0.1/projects/myfirstprogram.php

如果您确实创建了一个别名目录,请记住用您正在使用的别名替换projects

A978-1-4842-1730-6_1_Fig28_HTML.jpg

图 1-28。

EasyPHP alias screen

在 EasyPHP 中,可以从管理屏幕创建别名目录。转到系统托盘(屏幕右下角),右键单击 EasyPHP 图标,然后选择 Administration。在屏幕中间,找到本地文件,然后找到右侧的添加别名按钮。点击并按照指示操作。添加别名之前,该文件夹必须已经存在。

A978-1-4842-1730-6_1_Fig29_HTML.jpg

图 1-29。

The httpd-xampp file

在 XAMPP,这需要更多的工作。双击 XAMPP 图标打开系统面板。然后单击 Apache 右侧的 Config 按钮。从列表中选择httpd-xampp配置文件。选择编辑。从文本编辑器菜单中查找。搜索字符串'<IfModule alias_module>'。不要更改本节中已经列出的任何内容。但是,您可以为您的可执行文件添加位置(使用下面的代码)。一旦输入了所需的行,停止并启动 Apache 来帮助它找到新的变化。

Alias /myfiles "C:/Temp"

<Directory "C:/Temp">

Options Indexes FollowSymLinks MultiViews ExecCGI

AllowOverride All

Require all granted

</Directory>

有关创建别名目录的更多信息,请访问:

https://www.youtube.com/watch?v=XX6t3zJRXF8

Note

此目录设置允许对目录的完全读写能力。我们将在后面的章节中讨论保护“实时”网站目录的选项。

A978-1-4842-1730-6_1_Fig30_HTML.jpg

图 1-30。

Hello World running from the alias directory called myfiles as an index.php file

当用户在 URL 行中输入目录名myfiles时,这个清单将允许在 Apache 中执行C:/Temp目录中的任何文件。所提供的目录设置不太安全。然而,这只是为了在测试机上进行测试。如果你在一个真实的环境中,你需要加强directory标签下的安全设置。要执行这个目录中的文件,您可以在浏览器中输入 URL http://127.0.0.1/myfiles 。如果不包含文件名,Apache 将尝试查找一个index.htmlindex.php文件。如果两者都不存在,Apache 将使用当前设置列出目录中的文件。这允许容易地访问用于测试的文件。然而,在真实环境中,这并不是一个好主意。您可以通过添加文件名( http://127.0.0.1/myfiles/myfirstprogram.php )来请求不是索引文件的文件。如果必须更改端口号,请记住包括端口号( http://127.0.0.1:8080/myfiles/myfirstprogram.php )。当然,在浏览器中测试 URL 之前,目录必须存在并且文件必须在目录中。

做它

1.创建一个名为myfiles的别名文件夹,该文件夹指向硬盘或跳转驱动器上的现有位置。将您用来测试您的环境的hello world程序放在文件夹中。尝试使用前面的说明运行文件夹中的程序。你成功了吗?如果不是,你有什么问题?你是如何解决这些问题的?

记事本++编辑器和代码测试器

创建 PHP 代码时,您不需要使用特定的编辑器或购买编辑器。您可以在文本编辑器中(甚至在记事本中)创建所有代码。然而,拥有一个突出显示(着色)代码的编辑器确实有助于更容易地发现编码(语法)错误。

记事本++

A978-1-4842-1730-6_1_Fig31_HTML.jpg

图 1-31。

Hello World inside Notepad++

记事本++可在 www.notepad-plus-plus.org 下载。这是一个简单易用的编辑器。它可以创建超过 20 种不同形式的文件(包括 PHP)。本书中提供的大多数编码示例都是用 Notepad++创建的。当你在 Notepad++中创建新的 PHP 程序时,你必须告诉应用文件的类型。您可以通过选择语言菜单项,然后选择 PHP 来完成此操作。这将允许应用帮助您进行颜色编码和其他功能。

其他编辑

还有数百个其他可用的编辑器。我建议你挑一个你用起来最舒服的; www.download.com 是一个寻找 PHP 免费编辑的好网站。选择一个有很多用户和一个强大的评级。

如前所述,您可能还想试试 EasyPHP 的代码教室,网址是:

www.codeclassroom.net

做它

1.在使用这本书的时候,决定一个你将用来完成你的编码的文本编辑器。将编辑器下载到您的 PC 上。在编辑器中重新键入您的hello world程序,并保存该程序。从浏览器运行程序。你为什么选择你下载的编辑器?你喜欢编辑的什么?你不喜欢编辑的什么?

章节术语

| 服务器端编程语言(Professional Hypertext Preprocessor 的缩写) | 过程语言 | | 面向对象语言 | www.php.net | | 服务器 | 灯 | | 美国。 | 脚本语言 | | 程序设计语言 | Java Script 语言 | | 网络浏览器 | 源代码 | | 超文本标记语言 | 半铸钢ˌ钢性铸铁(Cast Semi-Steel) | | 脚本标签 | 网络服务器 | | print功能 | 街头流氓 | | 阿帕奇软件基金会 | 结构化查询语言 | | 数据库管理系统 | 静态页面 | | 动态页面 | 获取 HTTP 请求 | | 关系型数据库 | EasyPHP(开发者版本) | | 端口 80 | httpd.conf | | php.ini | XAMPP(洗发精) | | XAMPP 控制面板 | 别名目录 | | 开放源码 | 记事本++ |

第二章问题和项目

多重选择

MAMP stands for Mobile Application Motor Processor   My Awesome Mobile Program   Apache-MySQL-PHP   Modern Application Modular Programing   None of these     The goals of the Apache Software Foundation (ASP) include Coordination of all changes to the Apache web server   Overseeing the selling of all Apache software   Licensing all web servers   Maintaining membership to open source programming through the Apache web server     What scripting languages can be viewed within a web browser? Java   XML   JavaScript   PHP     Select the statements that are true about static web pages: They are sometimes called flat page/stationary pages   They are generated by a web application   Static web pages display the same information for all users   All of the above   A and C     ___________ is an object-oriented computer programming language commonly used to create interactive effects within web browsers. HTML   XML   JavaScript   PHP     What is the correct way to end a PHP statement? ;   New line   <!php>   .     The configurations button on the XAMPP Control Panel allow the user to do what? Install XAMPP   Select applications to automatically start   Manage add-ons   Configure MYSQL     php.net provides all of the following except Information of each latest release   PHP language documentation   LAMP, MAMP, and WAMP downloads   Contributions to the PHP documentation     Which of the following best describes a scripting language? The language is compiled.   The program must be compatible with operating system and hardware.   The first time the code is accessed is when the program is first executed.   The code is slower than compiled code    

真/假

The alias directory allows you to save your web page files in a directory (folder) of your choice rather than a www directory. It allows a URL address to point directly to that folder.   A static page is a page added to the dryer when drying clothes to prevent static cling.   A client browser submits a GET HTTP request to the server, then the server returns a response to the client browser.   The (Developer’s Version) of EasyPHP can be purchased only for one year at a time.   A dynamic web page never changes but a static web page is always changing.   WAMP stands for Windows, Apache, MySQL, and PHP.   Apache is an example of a web server.   HTML stands for Hypertext Markup Language.   PHP originally stood for Personal Home Page.   A procedural language is a programming language that uses classes and objects.   While viewing a web site in a browser, you may view the source code, which can show you HTML, JavaScript, and CSS. However, PHP code will not be visible.   Java is a procedural programming language.  

简答/短文

Explain the process that occurs when a browser requests a static web page.   Explain the process that occurs when a browser requests a dynamic web page.   Explain the difference between a procedural language and a scripting language.   How do you add access to PHP library code to your program?   Why should you use WAMP, MAMP, or LAMP instead of installing each application individually?  

项目

Create a PHP program to display a summary of your work history and educational history.   Create a PHP program to display your major and the courses required to complete your major.   Create a PHP program to display the goals and/or objectives of your college/university.  

学期项目

Your supervisor has requested that you design a secure application that will keep track of inventory in the warehouse of the ABC Computer Parts Corporation. This application will be accessible both within the warehouse itself and outside (via the Internet and/or smart phones). What data fields are necessary to keep track of this information? What size and data types (string, integer, floating point) should define these fields? What other restrictions on input (no negative values for item number) should be defined for these fields? For example, if a Social Security Number (SSN) was a required field: SSN: SIZE: Min: 9 characters (string) Max: 9 characters (string) Restrictions: Valid SSN format Notice that it uses characters, not integers, because no calculations will be done on the SSN number.

二、接口、平台、容器和三层编程

Electronic supplementary material The online version of this chapter (doi:10.​1007/​978-1-4842-1730-6_​2) contains supplementary material, which is available to authorized users.

"As of January 2013, more than 240 million websites (accounting for 39% of the sampled websites) and 2.1 million web servers have installed PHP."

——Ide,安迪(2013-01-31)。“PHP 只是增长&增长

章节目标/学生学习成果

完成本章后,学生将能够:

  • 给出可以托管 PHP 程序的平台或容器的例子
  • 使用 PHP 创建一个简单的动态 web 应用
  • 解释三层设计并确定每层包含的内容
  • 设计三层应用
  • 解释程序开发生命周期的每一步(PDLC)
  • 定义并解释 MVC 和依赖注入

PHP 平台和容器

PHP 是一种强大的语言,因为它可以适用于几乎任何硬件或软件平台。它与 HTML 和 JavaScript 接口的便利性为 PHP 应用提供了在任何可以托管浏览器的系统上运行的能力。越来越多的应用是使用浏览器作为应用的主要界面工具来创建的。这使得应用可以在 PC、互联网甚至智能手机上运行,而无需在设备上安装实际的应用(或其他软件)。它还允许用户在设备之间切换时体验相同的应用“感觉”。

在接下来的几节中,我们将简要介绍一些可以托管 PHP 应用的平台和容器。我们将互换使用平台和容器这两个词。在这个讨论中,我们认为平台或容器是一个软件工具,它“托管”PHP 程序和执行程序返回的任何输出。

PHP PC 应用

PHP 程序可以开发成运行在操作系统中的 PC 应用。然而,创建这些应用所需的技能要求深入理解操作系统和事件驱动的 PHP 程序之间的通信。这些高级技能超出了这本入门书所展示的概念。然而,有些人可能会认为完成这项工作所需的技能是不必要的,因为 PHP 程序可以在任何操作系统中的任何浏览器上运行。

PHP PC 应用确实具有“创建一次”和“在任何地方运行”的能力,就像其他语言(比如 Java)一样。PHP PC 应用可以被创建成不需要(或很少)在 PC 操作系统和硬件平台之间改变代码。

GTK SDK(软件开发工具包)是可用于 PC 应用开发的几种工具之一。如果你访问网站( http://gtk.php.net/ ),你可以找到最新版本和未来发展的信息。

If you are interested in PHP PC application development, try the link below or search for "PHP GTK Tutorial" in your browser. http://www.developertutorials.com/building-desktop-applications-in-php-8-02-01/

PHP 智能手机应用

PHP 也可以用来创建智能手机应用。通常,这是为了尝试将当前的 web 应用更新到智能手机环境中。智能手机应用开发需要在程序和智能手机操作系统之间开发通信链接的高级技能。

使用智能手机操作系统内置的一些功能(如 GPS)可能需要智能手机应用。所有智能手机操作系统都提供 API(应用接口)调用,允许手机上的应用使用这些功能。尽管 web 应用(将在本章后面讨论)可以在智能手机的浏览器中运行,但它们不能对智能手机操作系统进行 API 调用(因为它们不在手机本身中)。如果应用需要与智能手机操作系统交互的能力,它必须驻留在智能手机上。

开发智能手机应用需要高级编程技能和对智能手机操作系统的深入了解。使用目前可用的免费智能手机 SDK(软件开发工具包)可以减少一些麻烦。一些 SDK 现在提供了转换应用以在多种操作系统上使用的能力。

在尝试创建智能手机应用之前,您应该具备良好的基本 PHP 技能。

PHP 脸书和其他社交应用

PHP 可以用来创建托管在脸书画布平台和其他社交应用(如 Twitter)中的应用(和游戏)。这些应用中使用的技术是相似的。我们将简单地以脸书的油画为例。

应用可以使用工具在脸书本身(如脸书登录)使用 API(应用接口)调用。例如,应用可以使用脸书工具来监控应用的使用。当用户使用脸书登录功能登录到应用(或游戏)时,用户必须承认并接受运行该程序所需的安全级别。通过接受这些设置,用户授予应用进行 API 调用的权限,以便从用户的脸书环境中检索信息(可能是更改信息)。

您可以创建仅由脸书托管的 PHP 应用,而不需要 API 编程知识。许多包含用于更多信息的点进能力的广告被托管在画布中,但是实际上驻留在位于互联网上其他地方的 web 服务器上。脸书画布确实有能力解释 HTML 和 JavaScript 代码。这使得开发人员能够创建既可以在画布中显示又可以在外部浏览器中显示的应用。

让我们简单看看如何在脸书画布中托管应用。

您将保持“开发人员”模式的开发。这意味着当你完成演示后,脸书的每个人都将无法访问该应用。要使您的应用“活跃”,您还必须经历额外的步骤(详情见developers.facebook.com)。

Warning

脸书经常改变它的安全设置和 API(应用员接口)。随着时间的推移,下面的一些步骤可能会略有变化。如果你发现这些步骤不起作用,在互联网上搜索“一个简单的 PHP 脸书应用”,并检查教程或视频的创建日期,以确保你有最新的信息。

做它

完成以下工作:

For this example, you need to use your browser to search for an existing secure web page (one that uses https instead of http). Facebook no longer allows non-secured web pages to be hosted in the Canvas. Since this is a PHP book, it would be preferable to find a web application that includes PHP code (one that has a file ending of php instead of html). However, you can use an HTML site for this example. Remember, this is just for demonstration and educational purposes. You should always request permission to host a web site in another site (such as Facebook Canvas). All web sites are assumed to be protected by copyright laws (even when there is no indication on the site that they are copyrighted). Note: Some sites are secured to not allow their site to be hosted in another site. If you follow these directions and the site does not display, that may be the cause. If that happens, search for another secured web page. You could elect to use your own web page (such as the hello world example). However, the web page will need a hosting environment (besides your PC). Facebook cannot interface with your localhost development environment. There are many low-price hosting sites now available; some for as little as $1 a month. Most hosting companies enable you to have secured sites (using https). However, there is usually an additional fee for this service. When picking a host site, make sure to read the fine print to determine if it will host PHP applications. It is a good idea to have a hosting site for you to upload your test programs. Programs should be tested in multiple environments. Sometimes programs react differently in different environments. If you have your own secure URL, or one that your school allows you to use, upload your Hello World program onto the host. Then test it to make sure it still works in the host and make sure that you know the actual URL address that will run the program.   Sign in to Facebook ( www.facebook.com ). If you do not have a Facebook user ID/password, you can create one for free. This demo does not require you to completely build a Facebook page. If you have an existing account, you might consider creating an extra account (with a different e-mail address) just for your development needs.   Once you are signed in to Facebook, go to the developer’s page (developers.facebook.com). Find the Menu on the page. Select Apps, and then select Add New App. A screen similar to the one shown in Figure 2-1 will appear. Locate and select the Facebook Canvas option.

A978-1-4842-1730-6_2_Fig1_HTML.jpg

图 2-1。

Selecting Canvas from Facebook developer’s page (11/17/14) (Remember that Facebook does change their screens. However, the sign-in process should be similar to this demo.) The next screen requires you to enter a name for your application. Any unique name is fine since this application will not become live. You might also be prompted with some other questions related to whether this app is part of another app (no) and you may be requested to select a category (Apps for Pages would be fine). Once you have filled (and selected) the required information click the Create App ID button.   You should now see a Quick Start page similar to Figure 2-2. Ignore the code at the top of the Quick Start page (it’s beyond what we want to accomplish). Scroll down the page to find the textbox that says, “Where Is Your App Hosted?”. You may see a textbox (not required) that requests you to enter a unique URL for your app. If you do not enter one, Facebook will generate one. For our demo, we will leave it blank.

A978-1-4842-1730-6_2_Fig2_HTML.jpg

图 2-2。

The Facebook Quick Start page Another textbox requires you to enter a secure URL to link your app into Facebook. This is the actual location of your application on the Internet. Enter the complete address of the secure web page you have discovered or enter the location of your “Hello World” program if it is hosted on a secure site (https). Note: Facebook requires (at least) an ending slash for your link, something similar to: www.mysita.com/projects/myfirstprogram.php/ Click the Next button.   The next page displayed will show more example code. This code can be used to log in to your application using the Facebook login and has the ability to request Facebook permissions for your application. However, our demo does not need login ability or any Facebook permissions. Just click the Next button at the bottom of the page.

A978-1-4842-1730-6_2_Fig3_HTML.jpg

图 2-3。

The Facebook Open App page   Click the Open Your App button. Once you click the button, Facebook will try to load your page in the Canvas. However, if you have picked an existing secure web page and see a message similar to Figure 2-4, the page you selected might not allow hosting in another site. If this happens, go to Steps 7-10. If you were successful, skip to Step 11. However, copy and paste the URL (from the browser) that Facebook uses to display your page, so you can test it again, if needed.

A978-1-4842-1730-6_2_Fig4_HTML.jpg

图 2-4。

Facebook open app failure   If your page did not display, do the following. After you have copied the URL, close the test page. You now want to find the “Dashboard” for your app. If it is not visible on your Developers Facebook page, go to the menu at the top of the page and select Apps. A drop-down list should display showing the name of your app(s). Select your app.

A978-1-4842-1730-6_2_Fig5_HTML.jpg

图 2-5。

The Facebook dashboard   Once you have displayed your dashboard, select Settings on the left menu.

A978-1-4842-1730-6_2_Fig6_HTML.jpg

图 2-6。

The Facebook Settings page   Scroll down to the bottom of the page. Locate Secured Canvas URL and erase the address that resides in this textbox. Type the location of another secured web page (https) in the box. Remember, this must be a URL on the web, not your localhost. Click the Save Changes button.   Now paste the URL of your app (if you lost the URL address, it is under Canvas Page on the Settings Page) in your browser.

A978-1-4842-1730-6_2_Fig7_HTML.jpg

图 2-7。

Facebook working app   You should now see your app display on the canvas within your Facebook page.   Were you successful? What problems did you encounter following this example? How did you solve those problems?  

恭喜你,你已经创建了你的第一个脸书应用(虽然它不是实时的)。如果你想让你的一些朋友看到你的应用,你可以回到仪表盘,从菜单中选择滚动。然后,你可以使用你的朋友(是的,他们必须是脸书的朋友),并在你的应用开发中给他们一个“角色”(如“开发人员”或“测试人员”)。然后他们就可以访问你的应用,而不用它上线。

作为一名脸书游戏开发者,你正在走向赚大钱的道路!嗯,也许还不是时候。我们省略了许多代码来应对脸书的 API。但是希望您明白,脸书可以很容易地用作 PHP 应用的容器。

PHP、AJAX 和 CSS——网络应用

PHP 和 AJAX(异步 JavaScript 和 XML)配合得很好。AJAX 提供了动态改变部分网页而无需重新加载整个页面的能力。大多数网页都有静态区域(菜单、页眉和页脚),它们不会随着用户交互而改变。当用户与页面交互(点击按钮)时,网页的这些区域不必改变。AJAX 可以让您开发一个容器(在下面的例子中,容器位于div标记之间)来显示 web 服务器上托管的程序的输出;而不会扰乱整个网页。然后,当用户交互(单击按钮)的结果仍在处理中时,用户可以查看网页上的内容(菜单、页眉和页脚)。如果由于某种原因程序运行缓慢、挂起或丢失,页面的其余部分仍然可以运行。当您显示一个页面时,可能会遇到这种情况,该页面由于试图一次加载大量信息(大量广告)而挂起,并且该页面将无法运行,因为它必须在可用之前完全加载。

AJAX 还允许您在不干扰网页的情况下改变 web 服务器上 PHP 应用的内容。然后,您可以在用户不知情的情况下更新应用中的代码(只要您保持应用的名称不变)。

我们来看一个例子。

Note

代码示例文件包含在该书的网站上。您可以复制并使用这些示例,无需任何更改。我们已尽一切努力确保本书中显示的代码是正确的。打印错误可能会影响显示的代码(例如大写和小写被调整,括号被尖括号替换)。网站上的所有代码都是有效的。

Example 2-1. AJAX_Example_JavaScript.js

function getXMLHttp()

{

var xmlHttp;

try

{

xmlHttp = new XMLHttpRequest();

}

catch(e)

{

//Internet Explorer is different than the others

try

{

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

}

catch(e)

{

try

{

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

}

catch(e)

{

alert("Old browser? Upgrade today so you can use AJAX!")

return false;

}

}

}

return xmlHttp;

}

function AjaxRequest()

{

var xmlHttp = getXMLHttp();

xmlHttp.onreadystatechange = function()

{

if(xmlHttp.readyState == 4)

{

HandleResponse(xmlHttp.responseText);

}

}

xmlHttp.open("GET", "myfirstprogram.php", true);

xmlHttp.send(null);

}

function HandleResponse(response)

{

document.getElementById('AjaxResponse').innerHTML = response;

}

JavaScript, a scripting language, provides interactive capabilities for web pages. With JavaScript, the web page can respond to the user's input of information in the text box and/or clicking the button. If you need to review JavaScript or need more examples, please watch the free "New Boston" (D thenewboston.com) video: https://www.youtube.com/watch?v=yQaAGmHNn9s&list=PL46F0A159EC02DF82 To learn more about AJAX, please watch the free "New Boston" (thenewboston.com) video: https://www.youtube.com/playlist?list=PL6gx4Cwl9DGDiJSXfsJTASx9eMq_HlenQ .

如果你不懂 JavaScript,不要太在意这个程序的细节。我们只看几个关键点。AJAX 使用 HTTP GET 请求程序,类似于浏览器请求页面。在这个例子中,类XMLHttpRequest(存在于 JavaScript 库中)的一个实例被命名为XmlHttp。然后这个对象被用来打开对myfirstprogram.php的请求(就像打开一个管道)。然后对象的send方法发送请求(将水推下管道)。如果文件被正确返回,文件的输出将放在 HTML 网页上 ID 为AjaxResponsediv标签之间。如果浏览器不能处理 AJAX 通信,将显示一个警告框,建议用户升级浏览器。尽管不太可能有人使用不能解释 AJAX 代码的浏览器,但是您仍然应该处理所有的可能性。

Example 2-2. ajaxdemo.html

<head> <title>PHP Ajax Demo</title>

<meta charset="utf-8">

<link href="ajaxdemo.css" rel="stylesheet">

<script type='text/javascript' src='Ajax_Example_JavaScript.js'></script></head>

<body>

<div id="wrapper">

<div id="header"> <h1>PHP Ajax Demo</h1>  </div>

<div id="content">  <h2>"Watch it!!"</h2>

<p>The words below will be replaced by "Hello World" which is pulled from the 'myfirstprogram.php' file via AJAX.</p>

<h2>AJAX DEMO</h2>

<input type='button' onclick='AjaxRequest();' value='Find Hello World!'/><br /><br />

<div id='AjaxResponse'>

Pay attention… Notice when you click the button that only this section changes.

</div>  </div> <!-- end of content -->

<div id="footer">Copyright © 2015 Little Ocean Waves – Steve Prettyman

</div><!-- end of footer -->

</div> <!-- end of wrapper -->

</body></html>

要使用这个脚本,更改xmlHttp.open语句来选择您想要执行的文件(而不是myfirstprogram.php)。更改document.getElementById行,在 HTML 文件中包含您想要用来存放输出的div标记的 ID(而不是AjaxResponse)(参见下一个例子中的 HTML 代码)。HTML—超文本标记语言是一种用于格式化网页布局的标记语言。浏览器解释 HTML,然后向用户显示结果。要更深入地了解 HTML,请访问免费的“新波士顿”(thenewboston.com)视频:g https://www.youtube.com/playlist?list=PL081AC329706B2953

如果你对 HTML 不是很了解,不要担心。在这个例子中,你只需要看几行。首先,在代码顶部附近,一个链接标签拉入了ajaxdemo.css文件。这个 CSS 文件允许你看到一个有一些图形细节的页面。它允许您演示页面更新,而不需要 CSS 文件中的图形重新粘贴或闪烁。在这条线的正下方,脚本类型标签从示例 2-1 的 JavaScript 文件中加载。如果您将文件命名为其他名称,这一行需要用新文件名进行调整。如果您的文件不在同一个文件夹中,您应该在文件名中包含文件夹名称。

在 HTML body 部分的中间,input type 标记创建了一个按钮,单击该按钮将调用AjaxRequest函数(包含在 JavaScript 文件中)。这将导致示例 2-1 中的所有 JavaScript 代码执行。我们需要注意的最后一行是<div id='AjaxResponse'>标签。id ( AjaxResponse)中的值必须与 JavaScript getElementById代码中使用的对象名完全匹配。假设它们匹配正确,一旦点击按钮,JavaScript 代码将请求myfirstprogram.php文件并显示带有AjaxResponse ID 的div标签之间的结果。

Example 2-3. ajaxdemo.css

body { background-color: #000000;

font-family: Arial, Verdana, sans-serif; }

#wrapper { margin: 0 auto;

width: 85%;

min-width: 800px;

background-color: #cc0000;

color: #000066; }

#header { background-color: #ff0000;

color: #00005D; }

h1 { margin-bottom: 10px; }

#content { background-color: #ffffff;

color: #000000;

padding: 10px 20px;

overflow: auto; }

#footer { font-size: 80%;

text-align: center;

padding: 5px;

background-color: #0000FF;

color: #ffffff;

clear: both;}

h2 { color: #000000;

font-family: Arial, sans-serif; }

#floatright { float: right;

margin: 10px; }

为了完整起见,这里显示了 CSS 文件。不懂 CSS 也不用担心。这个文件只是让网站看起来更适合演示。如果您要使用该文件,请确保将其保存在扩展名为.css的文件中。此外,如果您要更改文件的名称,请确保也更改链接标记(在 HTML 文件中)中的文件名以完全匹配。如有必要,请确保包括所有文件夹名称。

CSS-Cascading Style Sheets (CSS) together with HTML display graphics on web pages. CSS describes the layout, color, text font, background image and other characteristics of the webpage. To learn more about CSS, please visit the free "New Boston" (thenewboston.com) video: https://www.thenewboston.com/videos.php?cat=40&video=18754g.

仔细检查所有三个文件(.js.css.html),确保文件名与调用它们的链接完全匹配。如果所有文件链接正确,首先显示ajaxdemo.html文件,如图 2-8 所示。

A978-1-4842-1730-6_2_Fig8_HTML.jpg

图 2-8。

ajaxdemo.html

如果您的代码不起作用,请仔细检查文件名(确保它们没有以.txt结尾)。如果你看到一个空白页,那就有问题了。在你的代码中寻找错别字。是不是忘了;{(或者其他编码?如果您收到一条错误消息,请将其粘贴到您的浏览器中,以发现可能的解决方案。如果你没有看到错误信息,请查看 Apache 和 PHP 的日志(见第一章)来确定其他可能的问题。

A978-1-4842-1730-6_2_Fig9_HTML.jpg

图 2-9。

The ajaxdemo.html file after the AJAX request

如果没有语法错误(或不正确的文件名或位置),当用户单击按钮时,页面将使用 AJAX 请求myfirstprogram.php文件,并将在div标记之间显示程序的执行结果。在这个例子中,Hello World将被显示。

做它

Copy the three files shown previously from the book’s web site into your projects folder (the location that you are running your projects in Apache). Run the HTML program. Was your test successful? If not, why not?   Change the file name of your .js file and change the link tag in your HTML file to reflect the new file name. Test your HTML program. Was your test successful? If not, why not?   Change the name of your PHP program. Make changes to the .js file to reflect the new name of your PHP program. Test your HTML program. Was your testing successful? If not, why not?  

PHP、AJAX 和 CSS——智能手机网络应用

至此,您应该开始发现创建 PHP 应用的灵活性和强大功能。您可能会有点失望,因为我们没有详细介绍智能手机的应用开发。如前所述,智能手机上的应用通常对操作系统进行 API 调用,请求使用手机上的应用(如 GPS)。那种程度的编码已经超越了入门级。因此,超出了这本书的内容。然而,有时我们希望为智能手机提供从手机浏览器访问 web 应用的能力。我们只需对之前的演示做一些修改就可以提供这种能力。这为您提供了一个适用于任何大小的包含浏览器的设备的应用。

您将在不调整 HTML(除了添加链接)、JavaScript 或 PHP 代码的情况下做出这一更改。您可以使用 CSS 在智能手机或其他移动设备中调整ajaxdemo网页的格式。在这个例子中,你只需要改变 HTML 文件来发现显示(界面)的大小。然后,CSS 可以用来改变图形,以适应适当的屏幕尺寸。

如果 PHP 文件包含大量 HTML(和/或其他 CSS 代码),我们可能也需要调整 PHP 文件。然而,我们应该总是考虑让 CSS 格式化整个输出(而不是 PHP 文件)。这将允许您在多个容器(主机)中使用相同的代码,正如您在本章中看到的演示。

您可以在ajaxdemo.html文件中原始 CSS 文件的链接下方添加以下行。

<link href="ajaxdemomobile.css" rel="stylesheet" media="only screen and (max-device-width:480px)">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Note

新的完整 HTML 文件位于该书的网站上。

这两行代码将尝试确定显示屏的大小,并将新的 CSS 文件用于 480px 或更小的屏幕。这个演示程序可以在大多数移动设备上运行。但是,让我们调整一下,去掉一些间距、填充和边距。

Note

您还可以将 CSS3 Flexbox 属性用于多种设备尺寸。由于它的使用需要对 CSS 有更多的了解,我们将坚持使用“旧风格”的方法。你可以在下面的 w3schools 链接找到更多关于 CSS3 Flexbox 的信息。

http://www.w3schools.com/css/css3_flexbox.asp

Example 2-4. The ajaxdemomobile.css file

body { background-color: #000000;

font-family: Arial, Verdana, sans-serif;

margin: 0;       }

#wrapper { margin: 0 auto;

width: 100%;

margin: 0;

min-width: 0px;

background-color: #cc0000;

color: #000066; }

#header { background-color: #ff0000;

color: #00005D;

font-size: 100%;

padding: 0.5px 0.5px 0.5px 0.5px; }

h1 { margin: 0px; }

#content { background-color: #ffffff;

color: #000000;

padding: 0.5px 0.5px;

overflow: auto; }

#footer { font-size: 80%;

text-align: left;

padding: 0px;

background-color: #0000FF;

color: #ffffff;

clear: both;}

h2 { color: #000000;

font-family: Arial, sans-serif;

margin: 0px;          }

#floatright { float: none;

margin: 0px; }

对比示例 2-4 和示例 2-3 。示例 2-4 中的代码并不完美,但它确实给了你一个在移动设备上显示的原始 CSS 文件中可以调整的概念。本示例将边距和填充减少到零,或几乎为零。这极大地减少了较小移动设备的显示器上浪费的空间。

做它

Locate the new HTML file and CSS file on the book’s web site. If you have a web host provider, upload these files (and the .js file) to the host. Try to access the HTML page from your smart phone. You can also try to display the page by using the URL location of the file on the book’s web site. Was your test successful? If not, why not? Did the page format properly on your phone? If not, what do you think needs to be adjusted?   Note

如果你在互联网上没有一个主机网站,你也可以通过下载一个免费的移动模拟器来测试这个 CSS 文件(试试 www.download.com )。你也可以改变 HTML 文件中的链接标签指向ajaxdemomobile.css文件而不是ajaxdemo.css文件。然后试着缩小你的浏览器来模拟智能手机屏幕。

PHP、HTML、JavaScript、CSS 和动态网页

作为 PHP 程序容器(主机)的最后一个例子,让我们考虑一下浏览器。正如你在本章中看到的,你可以使用一个 HTML 文件来调用我们的 PHP 程序(点击前面演示中的按钮)。如第一章中所详述的,这将导致 PHP 程序执行并将结果返回给浏览器。你也可以让你的 PHP 程序返回 HTML 代码。

Example 2-5. Dynamic HTML page created by a PHP program

<?php

print "<html>";

print "<head><title>My Program</title></head>";

print "<body>";

print "<h1>Hello World</h1>";

print "</body>";

print "</html>";

?>

您可以向请求执行 PHP 程序的设备(浏览器)返回一个完整的 HTML 页面(甚至包含 JavaScript 和链接)。示例 2-5 将从 PHP 代码中创建一个完整的动态 HTML 页面。创建的输出甚至可以包含指向 CSS 文件的链接和用于格式化的嵌入式 CSS 标签。然而,我强烈建议在嵌入依赖于容器大小的 CSS 标签时要小心。作为开发人员,您不知道哪种类型的设备会显示结果(PC、智能手机、平板电脑或 pad)。最好提供多个 CSS 文件(如前所示)来格式化不同设备的输出。

在前面的例子中,我们已经将初始界面(HTML 和 JavaScript)从 PHP 程序中分离出来。您实际上可以将 HTML(显示初始网页)和 PHP 代码放在同一个文件中。

您可以创建一个 PHP 文件来确定用户以前是否请求过该页面。如果没有,或者浏览器超时了,那么 PHP 程序会显示一个初始的 HTML 页面供用户交互(比如点击一个按钮)。然后,同一个程序可以再次调用自身来确定按钮是否被单击并返回响应。

让我们看一个不同版本的Hello World程序来完成这个任务。

Example 2-6. The callmyself.php file

<?php

if (isset($_POST['submitbutton']))

{

print "<h1> Hello World </h1>";

}

else

{

print "<html><head><title>PHP Example</title></head>";

print "<form method='post' action='callmyself.php'>";

print "<input type='submit' id='submitbutton' name='submitbutton' value='Find Hello World!'/>";

print "</form>";

print "</body></html>";

}

?>

为了更深入地演示 PHP If 语句,请访问以下来自“新波士顿”(The New Boston)的免费视频:www.thenewboston.com/videos.php?… = 17004。

这个程序包括一个简单的if条件语句来确定用户是否点击了提交按钮。

if语句的格式如下:

if (conditional statement)

{

// code to execute if the conditional statement is true

}

else

{

// code to execute if the conditional statement is false

}

条件语句通常比较两个值来确定它们是相同还是不同,或者调用返回truefalse值的方法。我们一会儿将看看返回值的函数。让我们看一个第一种类型的简单例子。

条件语句使用比较运算符(==, <, >, <=>=来确定语句是true还是false

If ( a > b)

{

print "it's A!";

}

else

{

print "it's B!";

}

在这个例子中,比较属性ab中的值。如果a大于b,那么“是 A!”显示。否则“是 B!”显示。当 PHP 认为有必要时,它会做一些类型转换。例如,假设a = "5",和b = 6。PHP 会将a中的值从字符串 5 转换为数字 5,这样它就可以进行比较。许多语言不这样做,如果您尝试比较字符串和数字,会显示一个错误。如果不希望发生这种转换,可以使用一些特殊的比较运算符。例如,您可以使用三个=符号而不是两个符号来查看值是否完全相同(a === b)。

And security-use = = instead of = = whenever possible. This will ensure that you get what you expect.

在示例 2-6 中,if语句调用一个方法(isset)。$_GET尝试检索属性('submitbutton')及其值(Find Hello World!")来自 HTML 表单,它使用 HTTP GET 来传递信息(您本来可以使用$_POST和 HTTP POST)。isset将向if语句返回一个falsetrue,这取决于$_GET是否可以检索属性(及其内容)。truefalse将导致if语句决定执行哪个代码块。

正如在第一章中提到的,HTML 表单中的一个对象(比如一个按钮)将根据对象的名称和包含在该对象的值语句中的内容产生一个属性和值的组合。对于已经给定了名称(id)和值的提交按钮也是如此(如示例 2-6 )。

第一次从浏览器调用程序时,按钮没有被单击。所以没有创建submitbutton变量。通过isset方法返回一个false。代码跳转到else部分并执行显示 HTML 表单和提交按钮的print语句(如图 2-10 )。

A978-1-4842-1730-6_2_Fig11_HTML.jpg

图 2-11。

callmyself.php after the button is clicked

A978-1-4842-1730-6_2_Fig10_HTML.jpg

图 2-10。

callmyself.php before the button is clicked

当用户点击按钮时,程序调用自己(看一下form标签的action参数)。这一次,因为用户已经单击了按钮,所以有一个 submitbutton 属性和一个变量的值('Find Hello World!')。程序确定变量是“set”(里面有一个值)并返回一个true。然后,if语句执行ifelse语句之间的一行代码。然后显示Hello World。PHP 程序处理应用的所有功能,而不使用任何现有的静态 HTML 页面。

这种技术的优点是所有代码都可以包含在一个文件中。因此,所有的变化都发生在一个地方。这种技术的缺点是所有代码都在一个文件中。代码越复杂,就可能变得越“混乱”。清理代码的一种方法是将代码转移到包含在其他 PHP 库中的函数中(我们将在后面讨论)。另一个缺点是,在不影响用户的情况下,不能更改文件名。如果您将文件名更改为mynewprogram.php,您将需要通知您的所有用户新的名称(可能还有位置)。前面使用 AJAX 的例子允许您在 HTML 代码页中更改文件名,但是不要求您更改用户请求的 HTML 页面的实际名称。

做它

Find the callmyself.php file on the book’s web site. Download the file to your Apache projects folder. Change and add print statements to display your complete name, the term, and your major. Test your program. Did your program run successfully? If not, why not?  

PHP 三层架构

这一章的大部分都在探索可以“托管”PHP 应用的不同平台(或容器)。我们发现 PHP 可以在几乎任何容器(PC、脸书、智能手机/移动设备或浏览器)中显示其输出。PHP 可以轻松地与 JavaScript、HTML 和 CSS 交互,这提供了这种灵活性。今天,几乎任何平台都有与互联网交互的能力(那些不具备这种能力的平台将在未来某个时候具备)。任何可以与互联网交互的平台也可以与 PHP 应用交互。

接口的这种独立性(或灵活性)展示了平台或接口主机与应用的其他“层”(部分)的逻辑分离。这就引出了对 PHP 应用的三层架构和逻辑设计的讨论。应用越大,就越有可能需要将应用分成模块。此外,这些模块更有可能驻留在不同的服务器(或 web 服务器)上。更大的应用可能需要多个程序员同时编写代码。这些程序员甚至可以使用不同的语言来创建程序模块。

构建一个大型应用与组装一辆汽车没有太大区别。汽车的各个部件(车身、车轮、电子设备和发动机)首先被单独组装。然后,每个完成的组件被放入汽车底盘内。然后将组件连接(软管、电线和皮带)到其他组件。完成后,汽车的所有部件一起工作。如果一个部件坏了,它可以被替换,而不会导致汽车中任何其他部件的替换或改变。

模块化(或组件)编程的思想是基于代码块的方法,这些代码块可以单独创建,然后与其他模块组装在一起,生成一个工作应用。这些模块可以被修改或替换,而不需要改变其他模块。这种方法已经存在一段时间了。即使在今天,许多程序也不是模块化的,因为较小的程序不需要分成模块也能有效地工作。然而,随着这些应用扩展成更大的应用,它们变得更加难以更新或维护。更改需要更新整个应用,而不仅仅是一个模块。在某种程度上,一个没有用模块创建的扩展应用必须从头开始重新设计成模块,以便更好地维护和提高可靠性。

正如在第一章中所讨论的,搜索引擎可以在用户电脑的浏览器中显示网页界面。一旦用户输入搜索请求,信息可以通过互联网传输到远程服务器(我们不知道在哪里),远程服务器执行搜索应用(我们不知道它是用什么程序语言创建的)。然后,应用在数据库(我们不知道是什么 DBMS,也不知道它在哪里)中搜索所请求的信息。结果被发送回应用,应用又将信息发送回用户 PC 上的浏览器(通过 web 服务器)。

A978-1-4842-1730-6_2_Fig12_HTML.jpg

图 2-12。

Three-tier modular application design

这个过程中的信息流使得这种类型的 web 应用的设计自然地分为(至少)三层(模块);接口层、业务规则层和数据层。将代码分成不同层的一个优点是能够在多个应用中重用层。例如,我们的搜索引擎可以为多种设备使用相同的业务规则层和数据层,同时使用不同的界面(PC 应用或智能手机应用)。不同的层也可以更新,而不会影响其他层。智能手机应用界面可以更新,以使用最新操作系统的最新功能,而无需更改业务规则或数据层。可以更新业务规则层中的代码来修复逻辑错误,而不需要更改接口或数据层。让我们看看每一层通常会发生什么。模块化的三层应用、设计和编程——三层设计提供了创建程序的能力,这些程序可以分为界面层、业务规则层和数据层。界面层包含与向用户显示信息相关的所有图形和程序代码。业务规则层不包含接口。但是,它处理从接口层提交的任何信息,然后可以将信息提交给数据层进行存储。数据层是应用的主要存储位置,可能包括数据库的使用。每一层都可以独立地更改和构建(编译),而不会影响其他层。

做它

What are the name of the three tiers of modular design?   How is modular design similar to designing a building?   How does modular programming make coding more efficient?  

界面层

A978-1-4842-1730-6_2_Fig13_HTML.jpg

图 2-13。

Interface tier

界面层(IT)显示信息,并为用户提供与应用交互的能力。大多数界面都提供了图形用户界面(GUI ),允许用户以一种吸引人的方式查看信息并与应用交互。GUI 界面提供通用对象,包括文本框和按钮,帮助用户快速适应新的应用。此外,图片、图像、图标、视频和声音也经常被包含进来,以保持用户的兴趣。通常还包括菜单和其他导航对象,以帮助用户成功地在应用中移动。对象——对象是已经被编译用于应用的代码块。通过创建对象的实例,可以将对象放入程序中。对象包含方法和属性。方法(或函数)是完成一项任务的代码块(例如将项目放入列表框中)。属性(或变量)是可以改变的对象的特征(如背景颜色)。对象通常经过良好的测试,没有错误。通过重用现有对象,程序员可以快速创建更可靠的程序。

这一层将使用对象(如标签和图片框)或脚本代码(如本章中的ajaxdemo.html示例)来显示信息。该层还将通过交互式对象(如文本框和按钮)接受来自用户的信息。静态信息可以在层内提供(通过菜单、徽标或页脚)。动态信息通常从业务规则层提供给业务规则层(例如本章中显示的myfirstprogram.php的输出)。

接口层中可能会出现一些编码(在后面的章节中介绍),用于准备发送到其他层的信息。例如,验证用户输入了所有必需信息或正确信息(年龄文本框中的数字字符)的 JavaScript 代码是可以接受的。附加代码还可以准备从业务规则层接收的信息,以便在界面中显示(例如将数字转换为文本格式)。

Verification/verification code-verification code verification information. The code compares the received information with the expected standard format. For example, the code can verify that the e-mail address contains both @ and. (period). If the information contains these two symbols, it can be considered as "valid" (although we are still not sure whether the email address really exists). Without these two symbols, the code is invalid. Invalid information usually causes the program to display an error message to the user, asking to re-enter valid information.

界面必须提供能够对用户交互(单击提交按钮)作出反应的代码,这通常称为用户事件。还可以提供代码来准备由用户提供的信息以供其他层使用(例如将用户输入的文本转换成数字格式以用于商业规则层中的计算)。事件——事件驱动语言(如 PHP)可以在事件发生时执行代码块。事件可以是用户已经完成的事情(比如点击按钮)。操作系统也可以触发事件。程序提供“听到”事件的监听器代码。当事件发生时,代码提供一个事件方法,然后执行该方法。程序通过侦听器代码的存在与否来选择要侦听的事件。

接口层不应该直接与数据库管理系统或数据库本身交互。通过这样做,这将把层锁定到数据库位置和数据库的实际设计中。该层不应操作数据(除了用于显示目的)。任何与应用本身相关的会计、数学计算或数据处理都应该在业务规则层完成。数据库管理系统(DBMS)——数据库管理系统是一种允许用户或应用创建和定义数据库的软件。它还提供了在数据库中插入、更新或删除信息的能力。

格式化数据以便显示从数据库访问数据
验证用户提供的信息是否正确计算结果
响应用户事件过程信息
处理意外情况(异常)验证用户 id 和密码
格式化业务规则层的数据 

做它

Give three examples of items that would be included in the interface tier.   Give three examples of items that would not be included in the interface tier.   Can some program code exist in the interface tier? If so, what tasks does this code provide?  

业务规则层

A978-1-4842-1730-6_2_Fig14_HTML.jpg

图 2-14。

Business rules tier

业务规则层处理从接口层和数据层收到的所有信息和数据。这个层还将返回接口层请求的信息(比如返回"Hello World"),并将信息提交给数据层进行存储。大多数实际的编程代码都包含在这一层中。

业务规则层代码通常使一个应用真正不同于另一个应用。如果一个应用是受版权保护的,那么独一无二的创造性算法可能就隐藏在这一层。例如,web 搜索引擎中的许多差异以及信息最终将如何显示都嵌入到业务规则层中。

与可能在浏览器中包含代码的界面层不同,业务层中的所有编码都是使用服务器上的程序(如 PHP)完成的。驻留在服务器上的脚本和编程代码由服务器本身保护,用户不能访问。业务层代码也可以驻留在应用服务器(作为服务)或 web 服务器(作为 web 服务)上。服务器通过不允许用户直接访问来确保这一层中的代码是安全的。

Server/application server /Web server-the server is connected to the network and provides services for any node (machine) on the network (or the Internet). Servers can provide multiple services (communication, security and/or storage) or specific services. The application server stores applications that users can access on the network (or Internet). The Web server hosts web pages and web applications. They are usually exposed to access outside the company. Service—A service is an application that resides in the memory of a computer or server and is used to respond to requests from other applications. Services can be automatically loaded into memory when the computer or server starts, or started and stopped manually when needed. Service has no GUI interface. The business rule layer can reside as a service on a computer or server.

如果在应用各层之间传递的信息可能会受到黑客的操纵,那么这一层可能会包含类似于接口层的代码,以验证所接收数据的格式是否有效和正确。

从这一层传递到其他层的信息可以被格式化以便于接受。例如,数据集(类似于表格或电子表格)可以返回到界面层,以便显示在网页上现有的表格或列表框中。数据集也可以被发送到数据层以插入到数据库中。数据集—数据集是一种可以容纳多个数据表的结构。数据表类似于数据库(包含行、列和数据)或电子表格中的表。数据集通常用于在层之间和方法之间传递信息。

业务规则层将值返回给请求它的层。该层不提供任何 GUI 界面或任何形式的表单。不需要界面,因为该层在任何时候都不与用户直接联系。所有与业务规则层的通信都是通过接口层或数据层来处理的。与接口层一样,业务规则层不直接更新数据库中存储的信息。所有存储更新都发生在数据层。

操纵数据显示信息
格式化数据在辅助设备上保存数据
将数据存储在内存中显示错误消息
引发异常 
验证数据 

做它

What tasks can business rule tier code accomplish that is similar to a task accomplished by code in the interface tier? Why is this code possibility duplicated in both tiers?   How does the business rules tier pass and receive data (information)?   Why must the business rules tier talk indirectly through the interface tier to provide information to the users?  

数据层

A978-1-4842-1730-6_2_Fig15_HTML.jpg

图 2-15。

Data tier

数据层的主要功能是在辅助设备上存储信息或将数据返回给业务规则层。数据可以(通常是)使用数据库管理系统(如 MySQL)存储在数据库中。该层与业务规则层相连接,因为在显示数据之前,可以对数据进行操作,就像创建报告一样。数据以业务规则层(和程序语言)可以接受的格式从该层返回。常见的格式包括 JSON、XML、SOAP 和数据集。JSON——JavaScript 对象符号是一种类似于 XML 的格式,用于存储和交换数据。JSON 可以在编辑器或浏览器中查看。它最常用于在层间传递数据。XML—可扩展标记语言是一种标记语言,类似于 HTML,用于存储和描述数据。XML 也可以用来在层之间传输数据。我们将在第三章中提供一个 XML 的例子。SOAP—简单对象访问协议用于与 web 服务交换数据。它与 HTTP(超文本传输协议)和 SMTP(简单邮件传输协议)一起提供应用和 web 服务之间的通信。Web 服务—没有接口的应用,可以被调用来处理信息。web 服务可以在 web 服务器上远程提供业务层和/或数据层的功能。web 服务描述语言(WSDL)用于描述对 web 服务的调用以及 Web 服务接受和返回的信息格式。WSDL 类似于 XML。

数据层的验证是在数据库管理系统中和/或通过程序代码完成的。这一层的验证是在数据库更新之前确保数据可靠和准确的最后机会。在存储验证问题之前发现它们比在记录无效信息之后发现它们要容易得多。

数据存储可以是本地和/或远程的。移动设备可以将存储限制在本地数据库(智能手机),但也可以使用 WSDL (web 服务)在服务器或云中(如微软 Azure)远程存储和检索信息。此外,许多应用使用 cookies 在本地保存少量信息,或者在远程数据库中保存大量信息。微软 Azure——微软 Azure 是一个云平台,提供数据服务、应用服务和网络服务。Visual Studio 应用可以在 Microsoft Azure cloud 中上传和保护。

数据层使用 SQL 语句(INSERT、DELETE、UPDATE 和 SELECT)检索和更新数据库中的信息。然而,对信息进行更改的实际请求来自业务规则层。例如,在 web 应用中请求地址更改的用户必须在接口层输入所请求的更改,在业务规则层格式化更新请求,并在数据层更改数据库中的信息。

在辅助设备上保存数据操纵数据
更新辅助设备上的数据显示错误消息
引发异常显示信息
验证数据 

做它

Why must the data tier validate information again, before it is placed in a database?   What type of code, if any, can exist in the data tier?   What is SQL used for?  

把这一切放在一起

程序开发生命周期(PDLC)引导我们完成应用开发的整个设计和创建过程。应用开发成功的关键是在开始编码和开发之前正确规划系统的布局。这样做可以减少可能出现的错误和问题。许多项目可能会陷入一个“角落”,由于事先计划不周,开发人员无法绕过这个角落。不同的作者和教师对计划过程中花费的时间的估计会有所不同,因为这是基于个人的。一个更有技能或更有经验的人可能比不自信的人做得更少。然而,每个人都至少计划好了所需的模块和模块之间流动的数据类型;即使只是在草稿纸上完成。同样,关键是在编码和开发过程中修改你的计划。当你开始编码时,你会发现“我没有想到”的情况。回去,然后调整你的计划。你这样做得越多,你就越不可能碰到一个你找不到办法绕过的“角落”。

在你的 PDLC 过程中,一定要让用户参与进来,同时要有一个强大的专家团队。请记住,您开发这个项目是为了让您的客户满意。你可能相信你有最终的设计和解决方案。然而,如果你的用户不同意你的观点,那也没关系。有时候,你确实需要调整自己的思维,以便更符合客户的需求。在这个行业工作时,我记得我的工作团队正在创建一个重大的变革管理系统(我很高兴没有参与这个项目)。设计者和编码者创建了一个非常花哨和昂贵的系统,一旦在数据中心实施,就很难使用。为什么?数据中心人员不想要花哨的系统;他们想要一个能够快速完成所需任务的简单系统。尽管最初的项目需要六个月才能完成,但一名数据中心员工利用自己的几个周末时间创建了另一个系统,实现了他们的目标。该系统在此后的许多年里一直被实施和使用。

通常,PDLC 由五个步骤定义;规划和信息收集、分析、设计、实施和评估。在计划和信息收集步骤中,集合了项目和项目团队的所有需求。还创建了初始文档来回答问题“我们试图完成什么?”“我们将如何完成它?”,以及“我们将使用哪个团队?”在分析步骤中,确定项目的可行性。文档回答了这样的问题“我们能用可用的团队和资源完成项目吗?”、“需要收集哪些额外资源?”,以及“项目能否在规定的时间和预算内完成?”如果项目通过了分析步骤(许多项目没有),那么实际的设计就开始了。在设计阶段,自顶向下的方法从首先查看整体所需的模块以及模块之间的数据流开始。随着所需方法的确定、平台的确定、通信工具的组合以及信息存储的设计,更多的细节将逐渐增加。

详细设计完成并获得批准后,项目将进入开发和测试阶段。单元测试(单个模块)和完整的应用测试都会发生。测试成功后,项目就可以进入实施阶段了。在实现过程中,必须决定如何安装项目以及何时安装。实现后,应用就“活”了。但是仍然应该进行持续的评估,以有效地确定需求、安全问题、逻辑问题以及项目可能的整体增强。最终,大多数项目会回到开发新版本过程的第一步。

本节假定规划、信息收集和分析步骤已经成功完成,这将使您进入设计步骤。总的来说,我们将关注决定什么类型的活动应该发生在应用的哪个层的过程。我们还将了解可能在各层之间流动的数据或信息的类型。在后面的章节中,我们将通过确定所需方法的类型以及必须流入和流出这些方法的信息和数据来完善这种分析。我们还将看看为这些方法创建的实际活动和代码。

最好的学习方法是通过实践,所以让我们看一个案例问题,然后从那里开始。

个案研究

公司:原子鱼孵化场有限公司。

项目:现场销售订单和佣金申请

范围:该应用将可从多种设备(移动设备和 PC)访问,以允许现场销售代理、经理和工资单人员轻松访问必要的信息。系统将接受来自销售代理的信息,这些信息将用于确定客户的购买成本、销售经理的销售量以及工资部门的佣金。项目的第一阶段是应用的开发,以接受来自销售代理的信息,显示购买成本,确定佣金,并将信息存储到 MySQL 数据库中。在成功测试平台后,它将被移动并安全保存在公司的云平台中。

输入(来自销售代理):销售代理编号、客户编号、订单编号、项目编号、数量和特殊需求

产出:(可能为未来阶段确定更多信息)

到数据库:除了来自销售代理的输入:佣金,销售总额

目标是确定每一层中将要出现的信息和流程的类型,以及各层之间的数据流。一旦确定下来,这些信息就可以用来开发一个通用的空层结构,这个结构最终将包含整个项目。

界面层

该公司已请求从多个设备进行访问。因此,我们必须记住,除了笔记本电脑和个人电脑之外,移动设备(平板电脑和智能手机)也将用于输入和输出信息。我们可以决定为每种类型的设备创建多个接口。使用三层设计,您可以设计一个共享业务规则层和数据层内容的系统,同时允许这种灵活性。

作为一名设计师和/或程序员,你必须确定将要输入的信息类型;几个字段(销售代理编号、客户编号、订单编号、项目编号和数量)都表示将输入数字。您需要确定这些字段的大小,并验证是否只输入了数字信息。“金额”字段是唯一可能在未来计算中使用的字段。因此,所有其他字段都可以保持文本格式。在将信息传递给业务规则层之前,需要将 Amount 字段转换为整数格式。特殊需求字段将是一个更大的字段,可以接受字母数字字符。该数据库目前不存在,因此您需要根据公司政策和/或当前使用的纸质表单来确定字段大小。审查后,确定客户和销售代理编号为八个字符。订单编号和项目编号目前是六个字符。

收集完这些信息后,您现在可以设计接口层的俯视图,如图 2-16 所示。

A978-1-4842-1730-6_2_Fig16_HTML.jpg

图 2-16。

Atomic Fish Hatchery Inc. sales and order application interface

销售代理可以多次使用带+的字段来输入所有信息。当创建实际的数据集和数据表时,必须有多个列可用于这些条目。

还会有一个额外的表单(未显示)来显示订单的结果。该表单将显示所购物品和总费用的摘要。所有信息都可以由销售代理输入、提交并保存在接口层(cookie?),直到销售代理表示订单已完成。然后,可以将信息转移到业务规则层进行处理。然后,业务规则层可以返回要在第二个表单中显示的信息。第二个表单可以包含一个“批准”(或取消)按钮。一旦获得“批准”,信息就可以传递到数据层进行存储。

业务规则层

业务规则层将包括两个流程。一个流程将接受完整的订单(数据集/数据表),并在销售代理单击“完成订单”按钮后确定总销售成本。然后,它会将该信息的摘要返回给第二个表单。当代理单击“批准”按钮时,将执行另一个流程。然后,该流程将确定佣金并创建一个数据集(现在有了额外的字段)传递给数据层。然后,信息将被传递存储。

此外,为了确保订单数据有效,需要一些方法来验证从接口接收的字段。业务规则层的俯视图如图 2-17 所示。

A978-1-4842-1730-6_2_Fig17_HTML.jpg

图 2-17。

Atomic sales and order application business rules tier

数据层

在这种情况下,数据层仅用于存储业务规则层提供的信息。该层将验证收到的信息,并将其存储到数据库中,如图 2-18 所示。

A978-1-4842-1730-6_2_Fig18_HTML.jpg

图 2-18。

Atomic sales and order application data tier

有许多工具可以在设计过程中提供帮助。重要的因素是设计者在过程中包括所有重要的信息。作为示例的替代,您可以从层中删除数据集的描述,并将它们放在层之间的数据流中,如图 2-19 所示。

A978-1-4842-1730-6_2_Fig19_HTML.jpg

图 2-19。

Alternate three-tier model

A978-1-4842-1730-6_2_Fig20_HTML.jpg

图 2-20。

Atomic Sales and Order Application Three-Tier Model

做它

When must you convert numbers to numeric form (such as Integer) for storage within a database?   Why use datasets to pass information between tiers?   What items have been missed or ignored in the case example?  

MVC 和依赖注入

MVC(模型-视图-控制器)是软件工程师(包括 PHP 应用设计人员)使用的一种设计模式,通过控制器在视图和模型之间进行通信。控制器是将任何用户输入传输到模型的软件。MVC 设计可以被认为是循环的,因为模型、控制器和视图能够相互通信。标准的三层模型是线性的;对于接收信息或向数据层传递信息的接口,它必须通过业务规则层传递信息。市场上有很多工具(比如 Ruby on Rails)可以帮助软件工程师设计 MVC 应用。

Visit thenewboston.com for a general example of MVC application: https://www.thenewboston.com/videos.php?cat=88

MVC 和基于组件的设计可以使用依赖注入。依赖注入允许程序(客户端)在不知道代码块的实际实现的情况下使用代码块(比如类)。这允许模块的独立开发、更新、测试和重用。这类似于汽车的点火装置与起动器通信的能力。点火装置对起动机部件及其工作原理知之甚少。它甚至不知道启动器的品牌。点火装置仅仅知道发送一个信号(电)给启动器,告诉它运行。如果更换了起动机,只要起动机在接收到信号时仍然工作,点火装置就不会察觉到这种变化,也不会受到这种变化的影响。虽然 MVC 和依赖注入是高级主题,但我们将在第四章的中探索依赖注入的例子。

章节术语

| 平台或集装箱 | GTK 软件开发工具包 | | 智能手机 API | 脸书帆布平台 | | 应用编程接口 | 脸书开发者页面 | | 创建交互式、快速动态网页应用的网页开发技术 | 字符串 | | XMLHttpRequest | document.getElementById | | 半铸钢ˌ钢性铸铁(Cast Semi-Steel) | 条件语句 | | 如果语句 | 三层架构 | | 界面层 | 业务规则层 | | 数据层 | 图形用户界面(GUI) | | 目标 | 验证码 | | 事件 | 数据库管理系统 | | 服务器 | 应用服务器 | | 网络服务器 | 服务 | | 资料组 | 数据 | | 可扩展置标语言 | 肥皂 | | 服务描述语言 | 结构化查询语言 | | Microsoft Azure | 聚合物分散液晶 | | 规划和信息收集 | 分析步骤 | | 设计步骤 | 实施步骤 | | 评估步骤 | 模型-视图-控制器 | | 依赖注入 |   |

第二章问题和项目

多重选择

The interface tier Is the primary storage location for the application, which may include the use of a database   Provides common objects, including textboxes and buttons, that help the user quickly adapt to new applications   Should be used for any accounting, mathematical calculations, or processing of data related to the application   Displays information and provides the user the ability to interact with the application     A service is an application that Can be manually started and stopped when required   Does not have an interface   Resides in the memory of a computer   All of the above     SOAP stands for Security Object Access Protocol   Simple Object Access Process   Simple Object Access Protocol   None of the above     The five steps of PDLC are Planning and Information Storing, Analysis, Design, Implementation, and Evaluation   Planning and Information Gathering, Analysis, Design, Implementation, and Evaluation   Planning and Information Gathering, Analysis, Data, Implementation, and Evaluation   Planning and Information Gathering, Analysis, Design, Observing, and Evaluation     The Web Service Description Language is used to Describe calls to the web server and the format of information sent and returned by the web service   Describe calls to the web service and the format of information accepted by the web service   Describe the code being used in HTML documents   Describe calls to the web service and discard the information received     CSS stands for Cascading Static Styles   Cascading Style Sheets   Cascading Script Sheets   Cache Style Scripts     What type of code belongs between the <script>……</script> tags? Java   HTML   Servlets   Javascript     What is the three-tier architecture composed of? GUI/tags/validation   interface/business/data access   Objects/variables/SQL   JSPs/servlets/sockets     The best description for the Model View Controller (MVC) is An architectural pattern that divides a given software application into three interconnected parts.   A programming language used to validate and secure information in any browser.   A type of validator mainly used to check if the user entered the information on the correct format   A type of method that is used to convert a harmful code so it cannot be executed by the compiler.     What is performed in the Analysis step? Determination of the feasibility of the project   Creation the code and error correction   Determination of the logical data flow of the project   Re-evaluation of the implemented application for possible improvements     Why must you validate your code? To determine the capabilities of the browser you are using   To make sure your information is correct and secure   To make sure that you have only JavaScript and HTML5 code   To check if your browser can run your code     What is the correct HTML syntax for referring to an external cascading style sheet? <stylesheet>my_style_sheet.css</stylesheet>   <link rel="stylesheet" type="text/css" href="my_style_sheet.css">   <style src="my_style_sheet.css">   None of these     Which tier is used to store and retrieve data? Presentation tier   Data tier   Application tier   None of these     What does SQL stand for? Structured Question Language   Structured Query Language   Strong Question Language     Which is true about smart phone APIs? The smart phone APIs allow procedural (method) calls to be made to the phones operating system.   The smart phone APIs will allow web applications to make procedural (method) calls to the phone’s operating system.   The smart phone APIs re not needed for applications that use GPS.   Not all smart phones come equipped with an API.     A dataset is similar to A paragraph of data   Sets of two words together   A table or spreadsheet   None of these    

对/错

Facebook Canvas Platform can accept apps written in any code, not just in PHP.   WSDL stands for Web Service Definition Language.   AJAX is used to create more interactive applications.   AJAX provides the ability to dynamically change portions of a web page with reloading the complete page.   When using the HTTP GET function, the URL must be in quotation marks.   A service is a function provided by a web server.   The design step comes after the analysis steps have been completed successfully.   MVC (Model-View-Controller) is a design pattern used by software engineers (including PHP application designers) to communicate between the view and model using a controller.   Planning and information gathering is part of the PDLC.   Dependency Injection allows the program client to enter a block of code to know the implementation of the block of code it will be using.   Objects are blocks of code that have already been compiled for use within an application.   HTML stands for Hypertext Markup Language.   Method signature includes the method name, and the number, types, and order of its parameter.   Datasets are not one of the many formats used when sending data between tiers in a three-tier architecture.  

简答/短文

In your own words, briefly describe each of the steps in the PDLC.   Why do you think development of PC applications using PHP has decreased?   Why do you think some web sites do not allow themselves to be inserted inside other sites (such as the Facebook Canvas)?   What are the advantages of creating web pages that use AJAX?  

项目

Using the steps of the PDLC demonstrated in this chapter, design the logic for a smart phone and mobile device application that allows your water meter reader to enter the full address and meter readings. The application should validate the information and send valid information to a MySQL database. If the information is not valid, a message should be displayed back to the user indicating the problem.   Adjust the AJAX example in this chapter (the code is available on the book’s web site) to display a mini version of your resume.   Adjust the Hello World (Example 2-6, callmyself.php) program to display your college/university name, address, and main phone number.  

学期项目

Using the information you have determined from the Chapter 1 Term Project assignment and the design techniques shown in this chapter, develop a logical design of the ABC Computer Parts Inventory application. This design should include all possible programs, interfaces, and data storage. The application design must be three-tier (interface, business rules, and data). Your final design should look similar to the examples shown in this chapter.

三、模块化程序设计

Electronic supplementary material The online version of this chapter (doi:10.​1007/​978-1-4842-1730-6_​3) contains supplementary material, which is available to authorized users.

“是的,我是一个糟糕的程序员,但我可能还是比你强:)”——拉斯马斯·勒德尔夫

章节目标/学生学习成果

完成本章后,学生将能够:

  • 创建一个没有错误的简单面向对象(OO)的模块化 PHP 程序
  • 创建一个 PHP 类并创建该类的一个实例(object)
  • 创建一个 OO PHP 封装程序,包括 GET 和 SET 方法
  • 创建接受参数并返回信息的 PHP 方法(函数)
  • 创建 PHP 公共和私有属性(变量)
  • 将现有的 PHP 代码从另一个文件或库中导入到程序中
  • 使用三元(条件)运算符验证收到的信息

PHP 库、扩展、类和对象

PHP 的优势之一是能够轻松地在库中存储代码模块。一旦代码被安装到一个库中,它就可以很容易地在其他程序中重用。对已经在“真实”环境中测试和使用过的代码的重用大大减少了程序错误并提高了生产率,因为您不必重新发明轮子。不需要重新创建已经成功运行的代码。这是浪费时间和精力,并且可能导致不必要的程序错误。程序员实际上可能不知道在一个代码模块(类)中实际存在什么代码。但是,程序员知道什么参数(比如数字)可以传入“黑盒”,从黑盒返回什么(数字的总和)。

您可能会担心程序员盲目地将信息传递到黑盒中,并盲目地接收信息。但是,这是优点,不是缺点。这允许模块的创建者在不影响模块使用方式的情况下更新代码。只要模块接受相同的输入并返回相同的输出,使用该模块的程序员就不会注意到任何变化。可以对模块进行更新,以便更有效、更安全,或者纠正任何程序代码问题,而不会导致用户改变他们在代码中处理模块的方式。

PHP 扩展

Example 3-1. Extensions in the php.ini file

extension=php_bz2.dll

extension=php_curl.dll

;extension=php_fileinfo.dll

extension=php_gd2.dll

;extension=php_gettext.dll

;extension=php_gmp.dll

;extension=php_intl.dll

;extension=php_imap.dll

;extension=php_interbase.dll

;extension=php_ldap.dll

extension=php_mbstring.dll

;extension=php_exif.dll

extension=php_mysql.dll

extension=php_mysqli.dll

;extension=php_oci8.dll

For a complete list and explanation of PHP extensions, please visit: http://php.net/manual/en/extensions.alphabetical.php .

PHP 有大量可用的库,有数千行经过良好测试的代码。示例 3-1 是php.ini文件的部分副本,显示了几个可以在 PHP 中激活的扩展(库)。每个库都是带有 PHP 包装器的 C 代码(为了更好地与 PHP 程序通信)。代码已经编译好了(注意.dll扩展)。存在于 PHP 环境中的库可以通过删除php.ini文件中扩展语句前面的注释符号(;)来激活。一旦保存了 INI 文件,必须重新加载 PHP 和 Apache(关于php.ini文件的位置和重新加载 PHP 和 Apache 的例子,参见第一章)。添加库的简便性是 PHP 如此受欢迎的原因之一。可以使用几种方法将附加的库“安装”到 PHP 中。比较流行的方法之一 Pear (PHP 扩展和应用库)处理第三方库的代码分发和维护。

The use of Pear and other third-party library installation methods is beyond the scope of this book. However, you can find more information in the links below. http://pear.php.net/manual/en/about.pear.php

此外,程序员可以通过requirerequire_once语句将他们自己的代码库(尚未编译)直接“安装”到应用中。在公司中,包含可以多次重用的代码是一种常见的做法(比如访问数据库)。通过在本地库中提供这种(经过良好测试的)代码,任何更改(比如将数据库移动到另一个服务器)都可以在一个位置(本地库文件)进行处理,而不需要更改多个文件。这也减少了代码冗余并增加了其可靠性。

虽然本地库可以只包含代码的方法(函数),但更常见的是模块(类)存在于这些库中。这允许程序员用前面提到的“黑盒”概念进行编码。三层架构(在第二章中解释)就是基于这个前提。通过引用包含代码的库,可以从库中访问代码类(通过requirerequire_once语句)。一旦进行了引用,就创建了类(对象)的一个实例。一旦创建了实例,程序代码就可以访问该对象的所有功能。

类和对象

一个类类似于一个房子的蓝图。蓝图包含建造房屋所需的所有要素的描述(特征)。然而,蓝图并不是实际的房子本身。它描述了如果我们雇佣一个团队来建造房子会发生什么。蓝图被认为是不存在的(就像房子会存在一样)。然而,它描述了建造房屋所需的物品(钉子、干墙和木材)和建造房屋的过程。

类描述了代码模块的特征(属性)以及代码中可能发生的动作(方法或函数)。但是,在创建该类的实例(称为对象)之前,它实际上并不存在(在内存中)。一旦创建了实例,就可以访问特征和方法。类和对象(当正确创建时)保护特征(属性)不被直接访问。这为对象提供了在更改发生之前验证任何更改属性值的请求是否有效的机会。这通常被称为封装。为了保护属性不被外界直接访问,应该使用private访问类型来声明它们。Private访问将只允许类中的方法能够更改属性中的值。Set方法(在本章后面讨论)被用来改变属性。Get方法(也将在本章后面讨论)通常用于检索属性值。

创建 PHP 类

让我们从创建一个类的基本结构开始。您将创建一个dog类,它将允许您设置狗的一些特征(大小、品种、颜色和名字),并且您将为狗提供说话和显示保存在每个属性中的值的能力。您将在一个单独的文件(库)中创建 dog 类,该文件可以在需要时加载到程序(或任何其他程序)中。

要创建一个 PHP 类,可以使用class关键字,并将类中的所有代码封装在{}中。

Example 3-2. Basic class structure in the dog.php file

<?php

class Dog

{

// all code is placed here

}

?>

如例 3-2 所示,class关键字是小写的。但是,类名Dog以大写字母开头。PHP 将允许你创建一个首字母小写的类。然而,通常的做法是通过使用大写的第一个字母来容易地识别类。包含您的类的实际文件名(dog.php)也应该匹配类名(Dog)。

For more information about classes, methods and properties, please visit PHP.net: http://php.net/manual/en/classobj.examples.php . For videos, please visit "New Boston: https://www.thenewboston.com/videos.php?cat=11&video=17175 .

类名不能包含空格。您还应该避免使用特殊字符。然而,_是允许的,通常用于连接两个单词(set_name)。您可能会注意到,一些类名在实际类名(__Myclass)前包含两个下划线(__)。然而,由于存在使用这种格式的“神奇的”类(我们将在本章后面讨论其中的两个类),这不是一种推荐的技术。

如前所述,类包含属性。属性也称为变量。属性包括类的特征。创建类的实例时,属性对于该对象是唯一的。操作系统会在内存中保留一个空间来保存这些属性。操作系统为我们处理内存管理,包括清理不再需要的属性。在 PHP 中,每当到达右括号(})时,操作系统的垃圾收集器就会安排删除已经创建的属性。此时,程序将无法再访问该属性。

属性可以保存许多不同类型的数据。在大多数语言中,当创建属性时,还必须包含一个数据类型来描述所存储的数据类型(如 string)。然而,PHP 不需要定义数据类型。第一次将数据放入属性中时,PHP 确定要存储在属性中的数据类型。属性是用一个首字母$和属性名创建的。属性名可以包括字母字符、数字和 可以用在属性的开头(在$之后)或者单词之间。不允许有空格。属性通常用小写字母创建。然而,PHP 允许大写字母。PHP 是区分大小写的,并且会考虑一个小写属性(speak)和一个大写属性(Speak)两种不同的属性。

Example 3-3. Basic class structure with properties in dog.php file

<?php

class Dog

{

private $dog_size = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

}

?>

程序设计建议——在 PHP 中动态创建属性。属性是在第一次使用时创建的。这既是帮助也是痛苦。如果你拼错了一个属性名,PHP 不会产生错误。相反,它将使用拼写错误的名称创建一个新属性。建议(如果可能的话)在程序(或方法,或类)的顶部用初始值创建属性,以便更容易地确定您的属性名是什么以及它是否已被创建。

如例 3-3 所示,Dog类的每个属性(除了$dog_size之外)都被声明为private,并且初始设置为一个字符串(文本)。$dog_size属性已经被设置为数字零(我们知道它是一个数字而不是一个字符串,因为零周围没有"")。操作系统将以 ASCII 格式将字符串值存储在属性($dog_breed$dog_color$dog_name中(用 0 和 1 的组合来表示每个字符),并将数值以数字格式存储在$dog_size属性中。当在程序中使用变量时,操作系统创建内存表来查找变量中值的实际内存地址。

Note

代码的格式还必须在代码语句的末尾包含分号(所有执行的代码行都必须包含分号)。

正如您可能注意到的,在这一点上,这个例子并不十分有用。即使要创建类的实例,也不能访问类中的任何内容或显示属性中的值。让我们向类中添加一个方法,让您可以显示类中包含的内容。为此,您需要创建一个使用print语句显示值的方法。您还可以借此机会使用字符串连接构建一个单独的输出字符串。

在 PHP 中,字符串连接有几种方式。在许多语言中,构建带有属性的字符串需要不断地打开和关闭一个字符串(使用"")。

print "Dog_weight is " . $this->dog_weight  . ". Dog breed is " . $this->dog_breed . "Dog color is " . $this->dog_color;

上面的print代码行在 PHP 中是有效的。然而,正如你所看到的,你有很多引号和很多句号。很难让一切都匹配正确。句点在 PHP 中是一个字符串连接字符,如果您选择使用这种技术,它将是必需的(在许多语言中,您将不得不使用类似的 madness)。但是,PHP 比这个友好多了。

This pointer-$this pointer is used to access the attributes contained in the object. this indicates that the code wants to retrieve the value contained in the attribute existing in a specific object (instance of class). Soon we will create an instance of the class named $lab. When the code that will exist in the $lab instance is executed, the $this pointer will tell the operating system that it only wants the values in the attributes (such as dog_weight) that exist in the $lab instance. Note that the format of this statement includes a $ symbol for the $this pointer, but does not include a symbol for the variable ($this->dog_weight). You may ask, why do we need the ?? pointer? The short answer is that you can create a property (called a static property) for each instance of the class. If the property of this type changes, it will change for all instances of the class. Our private property changes only in the specific instance ($lab) of the class that references it.

print "Dog weight is $this->dog_weight. Dog breed is $this->dog_breed. Dog color is $this->dog_color.";

PHP 允许在字符串(引号)中放置属性。这允许你使用更少的句号和引号(也许还能减少拔头发的次数)。

For an example of $this pointer, please visit: http://php.net/manual/en/language.oop5.basic.php For a video of $this pointer, please visit: https://www.thenewboston.com/videos.php?cat=11&video=17177

现在您已经有了生成输出所需的代码,您需要在类中添加一个方法来执行print行。一个类中发生的所有“动作”都必须包含在一个方法中。方法的创建方式与类类似(除了它们实际上包含在类中)。使用关键字function声明方法,后跟方法名和()。虽然 PHP 接受大写字符,但是方法名小写是常见的做法。_也可以包含在方法名的开头或内部。所有带有方法的代码都包含在{}中。

Example 3-4. Basic class structure with properties and a method in dog.php file

<?php

class Dog

{

private $dog_weight = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

function display_properties()

{

print "Dog weight is $this->dog_weight. Dog breed is $this->dog_breed. Dog color is $this->dog_color.";

}

}

?>

Program design suggestion-As shown in example 3-4 , it becomes more important to know the correct use of opening brackets and closing brackets ({and}). For every left parenthesis, there must be a right parenthesis. It's hard to know if you missed something. The editor (discussed in the first chapter) can help color-code everything to make it easier to see. In addition, indentation (as shown in example 3-4 ) helps to visually align the brackets. The PHP engine ignores extra spaces (called whitespace). Therefore, programmers can make the code look more comfortable and easier to debug.

这个类现在有能力执行一个动作(通过display_properties方法)。这样你就可以最终测试它的功能了。为此,来自示例 3-4 的代码必须放在dog.php文件(与类名相同)中,与将使用它的程序在同一位置。

我们现在需要创建一个程序来拉进这个库(通过require_once语句)。然后程序需要创建一个类的实例(Dog)。最后,程序将需要调用方法(display_properties)来显示属性的内容。

Programming suggestion-PHP will allow include, include_once, require and require_once statements to be used anywhere in the program code. This may lead to potential problems if it is used in the wrong place or used many times. It is strongly recommended to include these statements as close to the top of the code as possible, so as to facilitate viewing and determine whether the library has been installed. And security-PHP has several ways to introduce libraries into PHP programs. include The method will try to pull into a library. However, if the library does not exist, the program will continue to run (or crash). include The method does not care about the possibility that the library may have been attached to the code. A large program may accidentally try to pull into the same library several times (this will cause the program to crash due to duplicate methods and/or class names). include_once The method eliminates the possibility of multiple attempts to pull into the warehouse. If the library is already included, the statement will not be executed. If the library cannot be found, the require method does not allow the program to continue running. However, like the include method, it can try to pull into the same library several times. require_once method solves these potential problems. If you can't find the library, close the program; if you haven't installed the library, just install the library.

require_once语句的格式很简单。关键字require_once后面是库名(dog.php)。该语句应该包含在代码的顶部附近,并且在创建该类的实际实例之前(Dog)。

require_once("dog.php");

You can include the pathname in the require_once statement. However, it is recommended that you do not include absolute paths. For more information, please visit: http://php.net/manual/en/function.require-once.php For examples, please visit: https://www.thenewboston.com/videos.php?cat=11&video=17028 For videos, please visit: https://www.thenewboston.com/videos.php?cat=11&video=17029.

要创建一个类的实例,需要创建一个“指向”内存中该类实例的属性。包含关键字new是为了通知操作系统应该在内存中创建该类的一个实例(并且应该执行构造函数方法,后面会提到)。包含实际的类名是为了确定将哪个类构建到对象中。

$lab = new Dog;

这段代码将创建一个Dog类的实例,并用$lab属性(指针)引用它。为类的每个实例创建每个属性($dog_size$dog_breed$dog_color$dog_name的实际副本。这允许您更改该实例的属性($lab),而不更改其他实例的属性。

$lab->display_properties();

一旦创建了实例,就可以通过使用对象名($lab)和方法名(display_properties)来访问任何方法。

Example 3-5. Basic program structure including a library, object, and method call in lab.php

<?php

require_once('dog.php');

$lab = new Dog;

$lab->display_properties();

?>

图 3-1 显示了lab.php程序的成功输出,其中包含了dog.php文件中的Dog类。

For more examples of creating an object (an instance of a class), please visit: Example: http://php.net/manual/en/language.oop5.basic.php Video: https://www.thenewboston.com/videos.php?cat=11&video=17181.

A978-1-4842-1730-6_3_Fig1_HTML.jpg

图 3-1。

Output of lab.php

做它

Add a speak method to the Dog class to give each instance the ability to “bark”. Hint: Include a print (or echo) statement in your method. Add a call to your speak method after the call to the display_properties method in the lab.php file.   Create a second object from the Dog class in the lab.php file called $chow. Call the speak method (#1) to make him “bark”.   Create a new library file that contains a class of another animal of your choice. Within that class, create four properties that provide characteristics of that animal. Include a method that will print each of these characteristics. Also include a method that will cause the animal to speak. Create another file that will use this library file to create an instance of the class. The program should also call the method to display the properties and the method to cause the animal to speak.  

Error—If you encounter an error when trying this example, please check the following: Do you name the class (Dog) and the file name (dog.php) the same name? Make sure that the end of dog.php and lab.php files is .php instead of .txt. Is the file name exactly the same as that of dog.php in require_once statement in lab.php file? Are dog.php and lab.php files in the same folder? Are there the same number of left ({) and right (}) brackets in the two programs? Have you forgotten any semicolons (; )? For each statement of $thi, make sure that $ is a part of this, not a part of the attribute ($this->dog_weight). For any other errors, copy and paste your errors into the search engine to find possible solutions. Remember, errors may appear in Apache or PHP error logs (see Chapter 1 for details).

返回方法

在第二章的中,业务规则层被定义为包含返回请求信息的代码模块,但不提供显示返回数据的接口或格式。在前面的例子中,Dog类违反了这个要求。然而,您可以通过对dog.phplab.php文件进行一些代码修改来解决这个问题。

应该替换Dog类中的print语句。但是,您希望将多个值(dog_weightdog_colordog_breeddog_name)传递回调用它的程序。有许多方法可以完成这项任务。不过,既然你是刚开始编程,那就简单点吧。通过重新格式化原始字符串,我们可以很容易地创建一个逗号分隔的字符串。您可以将print语句替换为

Return "$this->dog_weight, $this->dog_breed, $this->dog_color.";

新的Dog类现在将包含示例 3-6 中显示的内容。

Example 3-6. Basic Dog class with return statement—dog.php

<?php

class Dog

{

private $dog_weight = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

function get_properties()

{

return "$this->dog_weight,$this->dog_breed,$this->dog_color.";

}

}

?>

Note

在 PHP 7 中,可以启用标量类型提示。PHP 7 为开发人员提供了声明预期返回的数据类型的能力。示例 3-6 中的函数可以编码如下。

declare(strict_types=1);

function get_properties() : string

{

return "$this->dog_weight,$this->dog_breed,$this->dog_color.";

}

如果不包含declare语句或strict_types=0,则不会强制数据类型。当前可以使用的有效数据类型有stringintfloatbool

由于标量类型提示不是向后兼容的,所以在本书的例子中没有使用它们。

您现在需要调整lab.php文件,以便能够接受从get_properties方法传回的内容(display_properties被重命名为get_properties,以反映它不再显示属性;它现在返回它们)。您可以通过在lab.php文件中创建一个属性来接收从get_properties方法传回的内容,从而实现这一点。

$dog_properties = $lab->get_properties();

如果您要使用print函数在此时显示$dog_properties,您将显示:

no weight, no breed, no color

然而,我们打算产生一个类似的结果,如前所示。您可以这样做,但是您需要能够根据分隔符“,”将字符串分成三部分。幸运的是,有一些 PHP 方法可以轻松完成这项任务。explode方法将根据分隔符断开一个字符串。然后可以使用一个list对象将子字符串(字符串片段)放入单独的属性中。根据我们的需要,您可以将$dog_properties字符串拆分如下。

list($dog_weight, $dog_breed, $dog_color) = explode(',', $dog_properties);

For more information about the function of explode, please visit: http://php.net/manual/en/function.explode.php

这将使no weight变成$dog_weightno breed变成$dog_breedno color变成$dog_color。这三个属性也是在同一行代码中的lab.php程序中创建的。我碰巧给他们起了和他们在Dog类中的同伴一样的名字。然而,请记住,如果您没有创建Dog类,您就不会知道原始的变量名。这没关系,因为你可以叫他们任何你想叫的名字,并完成同样的任务。

现在您已经有了包含信息的变量,您可以在lab.php程序中而不是在dog.php库中重新创建原始的print语句。

print "Dog weight is $dog_weight. Dog breed is $dog_breed. Dog color is $dog_color.";

请注意,您没有包括$this指针。您没有在类中执行该语句。您不创建lab.php程序的实例。程序只有一个实例(因为它不是一个类,不能有多个实例)。所以$this指针是不必要的。

新的lab.php程序现在看起来像示例 3-7 。

Example 3-7. The lab.php program with print statement

<?php

require_once("dog.php");

$lab = new Dog;

$dog_properties = $lab->get_properties();

list($dog_weight, $dog_breed, $dog_color) = explode(',', $dog_properties);

print "Dog weight is $dog_weight. Dog breed is $dog_breed. Dog color is $dog_color.";

?>

假设您的程序中没有错误,输出将与图 3-1 相同,与之前版本的程序没有变化。然而,Dog类现在满足了业务规则层的一个标准,它将信息返回给调用它的程序,而不试图格式化输出。lab.php 程序现在处理输出的格式化。

做它

Adjust the speak method in the dog.php file to return the bark string but not print it. Also adjust the call to the method in the lab.php file to display the output of the string. You can accept the string from the method and print the string in one line of code using syntax similar to the following: print $lab->speak();   Adjust the $chow object in the lab.php file to properly handle the return of the properties string and the speak string.   Adjust the animal class to return any strings instead of printing them. Adjust the program that makes an instance of the animal class to accept and display the strings that are returned.  

设置方法

这个例子仍然非常有限,因为您目前不能调整属性中的值来关联您创建的实际对象(比如$lab)。为了调整这些属性,您必须能够从使用该对象的程序中访问这些属性(lab.php)。但是,出于封装和安全方面的考虑,您不希望公开由调用程序直接操作的属性。面向对象的编程标准要求您将属性创建为“私有的”(正如您已经做的那样),然后使用类中的实际方法来更改任何值。

And security-creating a set method in a class provides the class with the ability to verify whether the information placed in the property is valid before the property is updated. If this verification is not performed before changing the attribute value, data corruption may occur. Afterwards, it may be impossible or very difficult to correct the accepted invalid data. Set The method can reject invalid data and return an error message to the caller.

一个set方法允许值被传递到方法中。然后,在更新对象中的属性之前,可以验证这些值。参数(值)被传递到方法调用中括号()之间的方法中。

$dog_error_message = $lab->set_dog_name('Fred');

如果set_dog_name方法存在于Dog类中,并且接受一个代表狗的名字的字符串,那么您可以使用一个类似于前面代码的方法调用。这个调用将把字符串"Fred"传递给set_dog_name方法。它还为set方法提供了向属性$dog_error_message返回值的能力,以指示属性是否被正确更新。您可以简单地从该方法返回一个'TRUE'或' FALSE '布尔值来指示更新的状态。然后,调用程序可以确定如何处理更新的状态。

如果你简单地传回一个'TRUE'或'FALSE',你可以使用 PHP 条件语句的简化版本,称为三元运算符来检查$dog_error_message

print $dog_error_message == TRUE ? 'Name update successful<br/>' : 'Name update not successful<br/>';

For more information about ternary conditional operators, please visit http://php.net/manual/en/language.operators.comparison.php Security and Performance-be careful when displaying error messages to actual users of applications. You can provide too much information to expose your program code unnecessarily. It may be safer to display general error messages to users. In real-time applications, log files should be created to record errors and access to the application itself.

使用这种格式,调用程序(lab.php)可以很容易地确定更新的状态并显示相应的消息。如果$dog_error_message中的字符串为“”),将显示?:(“Name update successful”)之间的信息。如果$dog_error_message中的值为'FALSE',将显示:;之间的字符串(“Name update not successful”)。

Example 3-8. The lab.php file with set methods and error checking

<?php

require_once("dog.php");

$lab = new Dog;

// -------------------Set Properties--------------------------

$dog_error_message = $lab->set_dog_name('Fred');

print $dog_error_message == TRUE ? 'Name update successful<br/>' : 'Name update not successful<br/>';

$dog_error_message = $lab->set_dog_weight(50);

print $dog_error_message == TRUE ? 'Weight update successful<br />' : 'Weight update not successful<br />';

$dog_error_message = $lab->set_dog_breed('Lab');

print $dog_error_message == TRUE ? 'Breed update successful<br />' : 'Breed update not successful<br />';

$dog_error_message = $lab->set_dog_color('Yellow');

print $dog_error_message == TRUE ? 'Color update successful<br />' : 'Color update not successful<br />';

//-----------------------------Get Properties---------------------------

$dog_properties = $lab->get_properties();

list($dog_weight, $dog_breed, $dog_color) = explode(',', $dog_properties);

print "Dog weight is $dog_weight. Dog breed is $dog_breed. Dog color is $dog_color.";

?>

在示例 3-8 中,lab.php现在能够将信息传递到Dog类的$lab对象的属性中。它还确定每个属性的更新是否成功,并做出相应的响应。在这个例子中,您有机会更有效地利用您创建的大量代码。然而,我们将推迟效率,直到你收集了更多的技能。

lab.php代码现在为每个要更新的属性(set_dog_nameset_dog_breedset_dog_weightset_dog_color)调用一个set方法,并将信息传递给每个方法。注意,字符串被传递到每个方法中,除了set_dog_weight方法,它接受一个整数。

现在您需要在Dog类中创建set方法。每个方法现在接受一个参数(字符串或整数)并返回一个'TRUE'或'FALSE'值。该方法的创建风格类似于您之前创建的get_properties方法。现在让我们保持验证过程简单,您将在后面的章节中学习如何改进它。

function set_dog_name($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) < 21) ? $this->dog_name = $value : $error_message = FALSE;

return $error_message;

}

set_dog_name方法将接受一个字符串到函数头(function set_dog_name($value))中定义的$value属性(参数)中。接下来,该方法创建属性$error_message,并提供初始值TRUE。该属性(连同$value属性)将只在方法执行时存在。一旦执行碰到了}右括号,这些属性将不再可用。

Programming considerations-TRUE and FALSE are constants and are part of PHP language. Constants cannot be changed, all of which are capitalized. TRUE is actually indicated internally as 1, while FALSE is indicated internally as 0.

Note

在 PHP 7 中,标量类型提示可以用来强制传递和返回的数据类型。

declare(strict_types = 1);

function set_dog_name(string $value) : string

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) < 21) ? $this->dog_name = $value : $error_message = FALSE;

return $error_message;

}

如果不包括声明行或strict_types = 0,数据类型将不会被强制。为了向后兼容,本教材中的例子不会显示标量类型提示的使用。

Programming considerations-&& is a AND operator. In order for (ctype_alpha($value) && strlen($value) < 21) statement to become TRUE, $value must contain only alphabetic characters and be less than 21 characters.

三元运算符查看$value属性的两种可能状态(包含传递给方法的任何内容)。

The ctype method is used to determine if the characters in $value are alphabetic (ctype_alpha($value)).   The strlen method is used to determine if the length of the string in $value is less than 21 characters (strlen($value) < 21).  

要了解更多的ctype功能,请访问: http://php.net/manual/en/book.ctype.php

如果$value属性只包含字母字符,并且少于 21 个字符,那么$dog_name属性将被更新为已传递的值。如果有非字母字符或字符串长度超过 20 个字符,则用FALSE值更新$error_message(表示更新没有发生)。最后,$error_message(或者TRUE或者FALSE)中的值被返回给调用程序。

And security-this process may be a bit confusing now. However, it is important to create a secure program. Every time an application or object receives information from an external source, such as another program or user, the information must be verified. This verification should include restrictions on the amount of information accepted, as well as other constraints. Data transmitted through the Internet (for example, from the user's browser to the network server) may be intercepted and changed. Before using information, it is very important to verify it in the application on the server. You can verify in the browser (through JavaScript) to ensure that the user has entered the correct information. However, as mentioned earlier, the packet interceptor can intercept this information and change it before the application on the web server receives it.

在查看代码更改之前,最后一点需要注意。PHP 提供了几个操作来比较两个值。下表总结了这些操作符,包括新的 PHP 7 Spaceship 操作符。

Operation            Result – returns TRUE if...

$a == $b             $a and $b are equal ignoring cases

$a === $b            $a and $b equal if case is the same

$a != $b, $a <> $b   $a and $b are not equal ignoring cases

$a !== $b            $a and $b are not equal or not same case

$a < $b              $a is less than $b

$a <= $b             $a is less than or equal to $b

$a > $b              $a is greater than $b

$a >= $b             $a is greater than or equal to $b

------------------------------------------------------

(Available with PHP 7)  $a <=> $b            returns -1 if $a < b, returns 0   if $a equals $b

returns 1 if $a > $b

此外,Null Coalesce 运算符可用于在三元运算中使用某个值之前检查该值是否“已设置”(包含某些内容)。

$dog_name = $_POST['value'] ?? 'No Name';

在这个例子中,如果某个东西存在于value中,那么它被放置在$dog_name中。如果没有设置value,则No Name被放置在$dog_name。这个操作符在 PHP 7 中是可用的。考虑到向后的能力,本书中的例子不会演示这个操作符。

让我们更新Dog类以包含所有需要的set方法。

<?php

class Dog

{

// ------------------------------------ Properties -----------------------------------------

private $dog_weight = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

}

Example 3-9. Dog class with set methods in dog.php

// ------------------------------ Set Methods ----------------------------------------------

function set_dog_name($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 20) ? $this->dog_name = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_weight($value)

{

$error_message = TRUE;

(ctype_digit($value) && ($value > 0 && $value <= 120)) ? $this->dog_weight = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_breed($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 35) ? $this->dog_breed = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_color($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 15) ? $this->dog_color = $value : $error_message = FALSE;

return $error_message;

}

}

function get_properties()

{

return "$this->dog_weight,$this->dog_breed,$this->dog_color.";

}

}

?>

Program design advice-when coding and testing your program, code only one set method. Then test the method to correct the error. When you have a successful set method, copy and paste it into your code, and make necessary changes. Don't try to code completely before testing the program. Program paragraph by paragraph, and then test. Although you may think this will slow down your coding speed, it is not the case. By catching every small error in the program, you can find them more easily. If you try to write a complete program, you may make many mistakes and spend a lot of time looking for each one. If it is difficult to find the error, comment out (use //) the new lines of code in the program, and then retest. If everything is all right, then gradually (only a few lines at a time) delete the comment line (//) from the code line and retest. This process should help you find lines of code that may cause problems. And security-in real world, programmers should not show users the details that cause the update to fail. Providing too much information may tell hackers what changes can be made to successfully update attributes containing invalid information. Pass the detailed information of the reason for the update failure to the security log file on the server.

代码开始变得冗长。然而,set的每个功能都非常相似。当您编写set函数时,您会发现这是一种常见现象。它还允许你通过复制粘贴工作方法并进行简单的修改,快速创建set方法。在示例 3-9 中,根据更新的信息类型确定不同的字符串长度。另外,$set_dog_weight方法检查传递的字符串中的数值,而不是字母字符。除此之外,方法几乎相同。

图 3-2 展示了当有效信息被传递到每个属性时的输出。显示“成功”消息。还要注意的是,get_properties方法显示了每个属性的新的更新值。在实际环境中,您可以考虑不显示成功的消息,而只显示不成功的消息。

A978-1-4842-1730-6_3_Fig2_HTML.jpg

图 3-2。

Output of successful update via set methods in Dog class—dog.php and lab.php

图 3-3 测试无效信息传递给set方法时产生的输出。请注意,默认值仍然在没有更新的属性中。这强调了包含默认值的需要,以防某些属性没有得到更新。在 PHP 中,显示为NULL(没有值)的属性通常会在输出中显示一个空格。例如,如果$dog_weight没有默认值,输出将显示"Dog weight is ."

Programming suggestion-Although PHP is friendly and tries to change null values to spaces when displaying, it is not a good programming method to assume this happens. Many programming languages will not do this conversion for you, and error messages will be displayed when trying to display attributes with a value of NULL. In addition, it is very important to set default values when using attributes for mathematical calculation. PHP will try again to convert the value of NULL to zero for calculation. However, in some cases, this will not happen and an error message will be displayed. In many programming languages, when trying to calculate with NULL value, an error message will appear. Establishing programming habits applicable to all languages will help you develop skills in multiple languages quickly.

A978-1-4842-1730-6_3_Fig3_HTML.jpg

图 3-3。

Output with invalid weight (1000) and invalid breed (‘Lab12’) in Dog class—dog.php and lab.php

做它

Create an additional property ($dog_gender) in the Dog class. Create a set method (set_dog_gender). Determine if a valid value (Male, Female) has been passed into the set method. You can use the following code or develop your own version to check for valid information. ($value == 'Male' || $value == 'Female') ? $this->dog_gender = $value : $error_message = FALSE;   Go to php.net and search for a method that will allow the checking of any case of “Male” or “Female” from #1. Update the conditional statement to allow any version (Male, MALE, male, Female, FEMALE, female, and so on). Hint: The characters in $value can be changed to all uppercase or all lowercase using the strtoupper or strtolower methods. Then check the string as all uppercase (MALE, FEMALE) or all lowercase (male, female) characters.  

获取方法

在我们之前的例子中,您创建了一个同时返回多个属性的get_properties方法。这是一个有效且有用的方法。然而,通常有一个get方法来匹配每个set方法。这为方法中的属性提供了write ( set方法)和read ( get方法)能力。在某些情况下,您可能只想提供一个没有 set 方法的get方法(使属性为只读)。我们可以(尽管很少这样做)提供一个没有get方法的set方法(使属性只写)。

Get方法实际上比set方法更容易编码。不需要验证数据,因为您正在读取数据,而不是更新数据。

function get_dog_name()

{

return $this->dog_name;

}

get方法中所需要的就是return语句,它返回属性中的值,而对象的用户不需要直接访问该属性。

Example 3-10. Dog class with set and get methods—dog.php

<?php

class Dog

{

// ----------------------------------------- Properties ------------------------------------

private $dog_weight = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

}

// ---------------------------------- Set Methods ------------------------------------------

function set_dog_name($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 20) ? $this->dog_name = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_weight($value)

{

$error_message = TRUE;

(ctype_digit($value) && ($value > 0 && $value <= 120)) ? $this->dog_weight = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_breed($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 35) ? $this->dog_breed = $value : $error_message = FALSE;

return $error_message;

}

function set_dog_color($value)

{

$error_message = TRUE;

(ctype_alpha($value) && strlen($value) <= 15) ? $this->dog_color = $value : $error_message = FALSE;

return $error_message;

}

// ----------------------------------------- Get Methods -----------------------------------

function get_dog_name()

{

return $this->dog_name;

}

function get_dog_weight()

{

return $this->dog_weight;

}

function get_dog_breed()

{

return $this->dog_breed;

}

function get_dog_color()

{

return $this->dog_color;

}

function get_properties()

{

return "$this->dog_weight,$this->dog_breed,$this->dog_color.";

}

}

?>

代码很长。然而,如前所述,像set方法一样,get方法彼此非常相似。一旦您创建了一个成功的get方法,您可以复制并粘贴它来创建其他方法。每个get方法需要改变的只是方法的名称和返回的属性。

Example 3-11. The lab.php program using set and get methods

<?php

require_once("dog.php");

$lab = new Dog;

// ------------------------------Set Properties--------------------------

$dog_error_message = $lab->set_dog_name('Fred');

print $dog_error_message == TRUE ? 'Name update successful<br/>' : 'Name update not successful<br/>';

$dog_error_message = $lab->set_dog_weight(50);

print $dog_error_message == TRUE ? 'Weight update successful<br />' : 'Weight update not successful<br />';

$dog_error_message = $lab->set_dog_breed('Lab');

print $dog_error_message == TRUE ? 'Breed update successful<br />' : 'Breed update not successful<br />';

$dog_error_message = $lab->set_dog_color('Yellow');

print $dog_error_message == TRUE ? 'Color update successful<br />' : 'Color update not successful<br />';

// ------------------------------Get Properties--------------------------

print $lab->get_dog_name() . "<br/>";

print $lab->get_dog_weight() . "<br />";

print $lab->get_dog_breed() . "<br />";

print $lab->get_dog_color() . "<br />";

$dog_properties = $lab->get_properties();

list($dog_weight, $dog_breed, $dog_color) = explode(',', $dog_properties);

print "Dog weight is $dog_weight. Dog breed is $dog_breed. Dog color is $dog_color.";

?>

当查看示例 3-11 中的代码时,请注意print语句调用了get方法(print $lab->get_dog_name() . "<br/>";)。操作的顺序,将在后面的章节中详细讨论,导致方法(get_dog_name())首先执行,尽管通常一行代码从左到右执行。该方法返回dog_name(字符串"Fred")中的值。该字符串被放置在方法调用所在的相同位置。在get方法执行之后,代码行现在是

print "Fred" . "<br/>";

然后代码行从左到右执行,产生输出

Fred <br/>

Programming considerations—Unlike attributes, methods cannot be enclosed in quotation marks (""or "). You must use "."to separate and join strings, as shown in the example. If a method is enclosed in quotation marks, PHP will display an error message.

如图 3-4 所示,get方法成功地在属性中显示了更新后的值。如果没有更新任何属性,get方法将显示默认值。

Programming advice-It is a good idea to display the values in the attributes frequently during the coding and testing stages to ensure that they are updated at the appropriate time. However, when you transfer the program from test mode to production mode, you should reduce the number displayed to users. It may not be necessary to display the updated value in the attribute to the user. Generally, it is best to only indicate the success of the update to the user. Before production, you can simply comment out unnecessary lines of print code. This will help to quickly debug the future upgrade of the application by simply deleting the comments in these lines.

A978-1-4842-1730-6_3_Fig4_HTML.jpg

图 3-4。

Dog class output with set and get methods

做它

In addition to creating an additional property ($dog_gender) and set method in the Dog class, create a get method to display the updated values. Also update the lab.php file to include a print statement (similar to the examples in this section) to call the get methods.  

构造函数方法

前面例子的一个难点是,如果您最初创建一个对象并用值填充该对象的属性,那么需要调用大量的set例程。Dog类要求您调用四个 set 方法(set_dog_nameset_dog_breedset_dog_colorset_dog_weight),以便在所有属性中放置值。您可以使用一种更有效的方式一次更新所有这些属性。这可以减少lab.php文件中的代码。在您提供初始值之后,您可以使用Dog类中的set例程来进行任何更改(也许狗增加了一些体重)。初始值不是默认值。您仍然需要默认值,以防初始值无效。

当在内存中创建一个类(对象)的实例时,操作系统执行一个构造函数方法,该方法用任何属性和方法构建对象。系统还在内存中建立表来跟踪对象的位置和对象属性中存在的值。当不再需要该对象时,操作系统的垃圾收集器将通过该对象的析构函数方法调用,这将把它从内存中移除。

您还可以包含一个构造函数方法,当对象被放入内存时,该方法将被自动调用。当创建对象($lab = new Dog;的代码行被执行时,它在对象中寻找一个构造函数方法。如果存在,则执行该方法。您可以通过创建对象的同一行将属性的所有初始值传递给这个构造函数方法。

$lab = new Dog('Fred', 'Lab', 'Yellow', 50);

这成为从lab.php程序中提供初始值的一种更有效的方式。

构造函数方法是一种通用格式,函数名为__ construct(注意在单词 construct 之前有两个下划线)。

<?php

class Dog

{

function __construct($value1, $value2, $value3, $value4)

{

// code to update properties

}

// other methods

}

?>

您可以在构造函数中使用现有的set方法来更新属性。您将需要收集任何消息(TRUE/FALSE)并将它们返回给调用程序(lab.php)。您可以使用与最初编码类似的过程来处理get_properties方法。

Example 3-12. Dog class with constructor—dog.php

<?php

class Dog

{

// ----------------------------------------- Properties ------------------------------------

private $dog_weight = 0;

private $dog_breed = "no breed";

private $dog_color = "no color";

private $dog_name = "no name";

private $error_message = "??";

// ---------------------------------- Constructor ------------------------------------------

function __construct($value1, $value2, $value3, $value4)

{

$name_error = $this->set_dog_name($value1) == TRUE ? 'TRUE,' : 'FALSE,';

$breed_error = $this->set_dog_breed($value2) == TRUE ? 'TRUE,' : 'FALSE,';

$color_error = $this->set_dog_color($value3) == TRUE ? 'TRUE,' : 'FALSE,';

$weight_error= $this->set_dog_weight($value4) == TRUE ? 'TRUE' : 'FALSE';

$this->error_message = $name_error . $breed_error . $color_error . $weight_error;

}

//------------------------------------toString----------------------------------------------

public function __toString()

{

return $this->error_message;

}

//... There are no other code changes to dog.php below this line.

For more information about the __construct method, please visit: Example: http://php.net/manual/en/language.oop5.decon.php Video: https://www.thenewboston.com/videos.php?cat=11&video=17181

首先,让我们讨论一下在示例 3-12 中称为__ toString(注意两个下划线)的特殊方法的使用。构造函数方法不允许返回信息(默认情况下)。在构造函数中不能使用return语句。为了将在构造函数中创建的错误消息返回给调用程序(lab.php),你必须欺骗程序。__toString方法允许程序员决定如果试图使用带有对象名(print $lab;)的print(或echo)方法会发生什么。通常会出现一条错误消息,声称对象不能转换为字符串(printecho只能显示字符串)。这可以通过在返回字符串的语句中包含一个__toString方法来覆盖。如果执行了print $lab;语句,您可以通过允许返回$error_message属性中的值来克服能够返回错误消息的问题。

For more information about __toString method and other magic methods, please visit http://php.net/manual/en/language.oop5.magic.php .

set方法返回的TRUEFALSE常量也会引起问题,因为它们是常量而不是字符串。如果您试图使用一个方法(比如strval(TRUE);)将这些常量转换成一个字符串,它们所代表的值(1 代表TRUE,0 代表FALSE)将变成一个字符串,而不是'TRUE'或'FALSE'。因此,它们不能通过__toString方法返回。为了克服这个问题,我们在构造函数中创建了下面的代码来进行从TRUE到’TRUE'或者从FALSE到’FALSE'的转换。

$name_error = $this->set_dog_name($value1) == TRUE ? 'TRUE,' : 'FALSE,';

操作的顺序将导致set_dog_name方法在代码的任何部分之前执行。set_dog_name方法返回TRUEFALSE(常量)。假设该方法在执行后返回一个TRUE,代码行现在应该是

$name_error = TRUE == TRUE ? 'TRUE,' : 'FALSE,';

操作顺序要求对比较(TRUE == TRUE)进行评估。当然,这评估为TRUE。使用了?:之间的语句。

$name_error = 'TRUE,';

因此$name_error被设置为字符串"TRUE,",它现在是一个字符串,而不是一个常量。

还要注意,已经添加了一个',',为下一个'TRUE'或'FALSE''值做准备。传递的每个值(除了最后一个值)必须用','分隔,以便稍后分隔字符串。

评估其他三个类似的行,并在错误消息属性中放置一个'TRUE、'或'FALSE、'(重量错误评估不包括字符串末尾的逗号,因为它是最后一个评估的)。

计算构造函数中的最后一行代码。

$this->error_message = $name_error . $breed_error . $color_error . $weight_error;

这一行将每个错误属性的值放入error_message属性中。如果所有的更新都成功了,$error_message属性将包含

"TRUE,TRUE,TRUE,TRUE"

请注意,除了最后一项之外,传递的每一项都包含一个“,”用于分隔。这对于分解字符串的结果是必要的。

Example 3-13. The lab.php file calling a constructor

<?php

require_once("dog.php");

$lab = new Dog('Fred','Lab','Yellow','100');

list($name_error, $breed_error, $color_error, $weight_error) = explode(',', $lab);

print $name_error == 'TRUE' ? 'Name update successful<br/>' : 'Name update not successful<br/>';

print $breed_error == 'TRUE' ? 'Breed update successful<br/>' : 'Breed update not successful<br/>';

print $color_error == 'TRUE' ? 'Color update successful<br/>' : 'Color update not successful<br/>';

print $weight_error == 'TRUE' ? 'Weight update successful<br/>' : 'Weight update not successful<br/>';

// ------------------------------Set Properties--------------------------

...There are no other changes to lab.php below this line.

示例 3-13 第三行的对象创建略有变化。

$lab = new Dog('Fred','Lab','Yellow','100');

您现在通过构造函数将初始值(FredLabYellow100)传递给对象。否则,您将不得不四次调用set方法(set_dog_nameset_dog_breedset_dog_colorset_dog_weight)来完成同样的事情。这允许您使用set方法进行最初设置对象后所需的更新($lab)。

为了确定对四个属性的更新是否成功,您必须从对象的$error_message属性中检索您的值(TRUETRUETRUETRUE)。在Dog类中的__toString方法允许你把$lab当作一个字符串来处理。这允许您在类似于get_properties方法输出的过程中使用explode方法。

list($name_error, $breed_error, $color_error, $weight_error) = explode(',', $lab);

这一行代码将把$lab ( TRUETRUETRUETRUE)的内容用逗号分开,并将每个部分放入属性$name_error$breed_error$color_error$weight_error。现在,这些属性中的每一个都将包含字符串'TRUE'。然后,您可以评估您的消息,以类似于评估set方法结果的技术来查看更新是否成功。

print $name_error == 'TRUE' ? 'Name update successful<br/>' : 'Name update not successful<br/>';

在评估set方法的结果时,这种格式和类似的语句之间只有一些微小的区别。这些代码行中的每一行都使用不同的错误消息进行评估($name_error$breed_error$color_error$weight_error)。之前,您对 set 方法的所有结果使用了相同的属性($error_message)。您现在评估的是字符串'TRUE'而不是常量TRUE(代码中唯一的区别是实际的引号)。

在图 3-5 中,前四行输出是通过将值传递给构造函数来为每个属性提供初始设置而产生的。当使用set方法更改属性中的值时,将产生接下来的四行输出。最后四行是通过执行get方法产生的(显示每个属性的内容)。最后一行输出是由get_properties方法产生的。虽然初始值(FredLabYellow100)被成功地传递到构造函数中,但是每个属性中的值都是使用 set 方法(传递SallyLabradorBrown5)更改的。

And security-some people think that checking for errors every time you update is redundant. However, in the current environment where people are constantly trying to destroy data, we must be as careful as possible when updating. No program can 100% avoid data corruption. I hope you have noticed that once you develop a routine to check data, your data check code lines will become very similar every time. Therefore, by copying and pasting (slightly modifying) the code lines that successfully verify the data, you can greatly improve the security without adding a lot of extra coding time.

A978-1-4842-1730-6_3_Fig5_HTML.jpg

图 3-5。

Output from dog.php and lab.php with the constructor, set, and get methods

做它

This chapter has covered a lot of PHP examples and terms. To help clarify any difficulties you might currently be experiencing in understanding the PHP language, visit this web site for additional tutorials: http://www.w3schools.com/php/default.asp   Update the constructor in the Dog class to also allow the passing of the dog_gender value (Male or Female). Update the lab.php program to pass the gender through the constructor. Also update lab.php to explode the $lab string into five parts (one more for the dog_gender). Then evaluate the results ('TRUE' or 'FALSE') returned from the gender_error to display "Gender update successful" or "Gender update not successful".  

章节术语

| PHP 扩展 | 梨树 | | require | require_once | | 班级 | 性能 | | 变量 | 方法 | | 功能 | 目标 | | 包装 | 私人的 | | set方法 | get方法 | | $this指针 | 串并置 | | Include | include_once | | new关键字 | return | | 逗号分隔的字符串 | explode方法 | | 子链 | set方法 | | 布尔值 | 条件语句 | | 三元运算符 | 整数 | | 参数 | 零合并运算符 | | &&, And | ctype_alpha | | strlen | ctype_digit | | &#124;&#124;, Or | 宇宙飞船操作员 | | 空 | 操作顺序 | | 构造函数方法 | 析构函数方法 | | __toString | 列表对象 |

第二章问题和项目

多重选择

PHP variables begin with which symbol? ?   !   $   &     A valid function name can start with which of the following? A letter   An underscore   A number   Both A and B     Which conditional statement syntax is valid for PHP? IF (condition) { execution };   IF (condition) { execution }   if (condition) { execution };   if (condition) {execution}     Which of the following includes properties and actions (methods or functions) that can occur in an application? Class   set method   get method   for loop     Which basic function does a constructor method perform? Defines properties   Defines methods   Places an instance of a class into memory   A and B     The && symbol and/or the word AND Are relational operators, when used, and require all statements checked to be true for the complete if statement to be considered true   Are conjunctions used in PHP to connect programs   Are relational operators, when used, and require that only one statement checked to be true for the complete if statement to be considered true   Are relational operators and conjunctions used in PHP to connect programs     An integer is which of the following? A string or text value   A floating-point number   A whole number   A fraction     A ternary operator is which of the following? An alternative to setting a variable   An alternative to using an if-else conditional statement   An alternative to using an embedded if-else conditional statement   B and C     How does one create an instance of the class fred and execute the constructor method in PHP? $this->fred   $variable = new fred   $load_class = fred   $fred     What purpose does the method ctype_digit serve? Randomly generates an integer value   Determines whether characters inputted are numeric   Determines whether a class output is numeric   Converts a string value to an integer     Pear is an acronym for PHP Extends and Applies Registry   PHP Excellence in Applied Requirements   PHP Extension and Application Repository   Properties of Extension and Application Registry     Creating set methods inside classes Allows properties to be changed automatically   Should not be done as it corrupts data   Provides the ability for the class to verify information before the property is updated   Provides the ability for the class to verify information after the property is updated     if statements Are also called conditional statements   Can compare two values to determine if they are the same or different   Use comparison operators (==, <, >, <=, >=) to determine if the statement is true or false   All of the above     $x && $y condition is TRUE if Both $x and $y are true   $x or $y are true   Both $x and $y are false   $x or $y are false     Select the statement about Boolean values that is false. Boolean is a data type having two possible values—TRUE and FALSE   Boolean values represent the truth values of logic   Boolean values are only associated with conditional statements   In PHP Boolean literals, TRUE and FALSE are case-sensitive     Which one of these numbers is an example of an integer? 1.01   2f   423   .002     Protecting an object’s data from code outside the class is called what? Inheritance   Encapsulation   Classification   Blocking     Which kind of methods are easier to code than set methods and are known as read only methods since they do not change any property values? explode methods   get methods   constructor methods   match methods     Why would you include objects in your program? To make notes in your code   To make mini mobile programs   To make your code more complex   To protect your code from direct access     How do you call a function named myFunction? call myFunction();   myFunction();   call function myFunction;   call.myFunction();     A class can contain all of the following except Properties   Methods or functions   Conditional statements   Machine code     When working with a comma-delimited string, which character is used to separate the data in the string? Space   Semicolon   Asterisk   Comma    

对/错

Methods are functions that belong to a class.   You would use the symbol || or the word or when you want both conditions to be true.   When a function is private, it can only be used inside the class in which it exists.   The explode method can be used to separate a string at the specified delimiter.   The new keyword tells the operating system that an instance of that class should be created in memory.   The function Ctype_alpha will return true when a number is passed into it.   require_once will not execute if the file has already been attached to the program.   The ctype_digit function determines if the characters passed are alphabetic.   The ctype_alpha function determines if the characters passed are alphabetic.   A PHP constructor has the same name as the class.   A ternary operator is shorthand for a while loop.   If a file has already been included in a program, the require_once function will generate only a warning and allow the program to continue.   Destructor methods are called when there are no remaining references to an object or when that object has been explicitly destroyed.   Objects are blocks of code that have already been compiled for use in an application.   The else statement extends an if statement by allowing code to execute when the if statement evaluates to FALSE.   include or require statements can only be placed at the top of an PHP program.   Programmers can pull their own libraries of code into an application via the require or require_once statement.  

简答/短文

Explain the meaning of encapsulation and how classes are encapsulated.   Why should a programmer use set and get methods?   Why should every entry on a web page from a user be validated?  

项目

Create a PHP program with a class (Student) with the following properties: student_id, student_name, student_address, student_state, student_zip, and student_age. The program includes get and set methods for each property. Validate the proper type and size of data passed into each property. The program also includes the ability for each property to use the constructor to set values. Create an instance of the class passing properties through the constructor. Change two of the properties using set methods. Display the properties using get methods.   Create a PHP program to keep track of inventory within a grocery store. Each item (class) includes an item number, description, size, self, isle, amount, and price. Each field must be verified for proper information before the entries are accepted. Item numbers range from 00000 to 99999. The store has 16 isles (00-15). No price in the store is greater than $1000. All entries are coded via a constructor or set methods. After all entries have correctly been accepted, the program will generate a report of the entries (using get methods).  

学期项目

Using the design from the Chapter 2 Term Project, create a PHP program that will provide the interface for entering in the ABC Computer Parts Corporation inventory items for the warehouse. The PHP class must verify the contents of the information passed from each field (via the set methods) to ensure that no corruption has taken place. Set and Get methods for each property must exist in the class. The constructor should use the set methods to populate the properties. Also create an interface program that will make an instance of the class and test the ability to populate the properties. The test program should generate a report of the item placed in inventory (similar to the output shown in this chapter). The files created should use logic similar to what was shown in the examples in this chapter.