PHP中阶,PHP进阶
PHP功能的强大首先在于它的大量的内置函数库,它可以让初学者也能执行许多复杂的任务,而不必安装新的库和关心底层的详细情况,而这恰恰是其它流行的诸如Perl这样的客户端语言所不具备的。由于这个教程的限制,我们仅仅学习了一些与MySQL数据库相关的一些函数(事实上,即使是这种函数,我们也没有学全)。在这最后的部分,我们会稍微扩大一下范围来看看其它对于建立一个数据库驱动的网站有用的PHP的特征。
我们首先将学习PHP的include函数,使用这个函数,我们可以在许多页面中重复使用同一个PHP代码段。我们还看到如何利用这个函数提高我们的网站的安全性。
虽然PHP一般是相当快速和有效率的,但是它会加重服务器的运行时间和工作量。对于一个高流量的站点来说,这种负担可能会达到无法接受的程度。但是这并不意味着我们需要放弃我们的站点的数据库驱动的特征。我们会看到如何使用PHP在后台建立半动态页面而不必过分加重服务器的负担。
经常有人问论坛是如何利用一个标记来接受文件的上载的。我们也将学习到如何用PHP实现这种功能,而且我们还会看到如果将其有效地结合到一个数据库驱动的站点中。
最后,PHP还有一个相当强大的功能是可以很简单地将动态生成的内容很方便地作为email的信息发送出去。不论你是想要使用PHP使得访问者将你的站点的内容发送给它们的朋友,还是仅仅想提供一种方法让用户可以得到他们遗忘的口令,PHP的email函数都可以很好地实现这种功能!
PHP的服务器端包含
如果你已经在Internet上工作过一段时间,你也许接触过服务器端包含(SSI)这个术语;如果你没有接触过,你可以参看有关这个问题的Matt Mickiewicz的迷你指南。
从本质上说,SSI允许你将存储在你的Web服务器上的某一个文件的内容插入到另一个文件中去,最常见的应用是将一个网站的公用设计部分写入一个小的HTML文件当中,这个文件可以被Web页面所包含。对这个小文件的所有变动立即会影响所有包含它的文件。就象一个PHP脚本一样,Web的浏览者不需要对此有所了解,因为Web服务器会在将被请求的页面发送到浏览器之前做好所有的工作。
PHP有一个函数可以提供类似的功能。但是在包含文件中除了可以含有正式的HTML以及其它静态的内容以外,还可以含有脚本程序。让我们来看看下面这个例子:
Soylent Green is made from people! ");
?>
在上面的文件中,include-me.inc包含了一些简单的PHP代码。请注意这个文件的文件名的结尾是.inc,而不是.php。这表示这个文件与一般的Web服务器所认为的PHP脚本有所不同。这会保证这个文件只有被插入到一个.php文件中才会被执行,此外这也有助于你分辨你的PHP Web页面和PHP包含文件。
你还需要下面的文件:
Test of PHP Includes
Generating
Generating ...
Unable to load $srcurl. Static page ".
"update aborted!");
exit();
}
//将这个URL的内容读入到一个PHP变量中。
//指定我们将读取1MB的数据(超过这个数据量一般是意味着出错了)。
$htmldata = fread($dynpage, 1024*1024);
//当我们完成工作后,关闭到源“文件”的连接。
fclose($dynpage);
//打开临时文件(同时在这个过程中建立)以用来写入(注意'w'的用法).
$tempfile = fopen($tempfilename, 'w');
//处理错误
if (!$tempfile) {
echo("
Unable to open temporary file ".
"($tempfilename) for writing. Static page ".
"update aborted!");
exit();
}
//将静态页面的数据写入到临时文件中
fwrite($tempfile, $htmldata);
//完成写入后,关闭临时文件。
fclose($tempfile);
//如果到了这里,我们应该已经成功地写好了一个临时文件,
//现在我们可以用它来覆盖原来的静态页面了。
$ok = copy($tempfilename, $targetfilename);
//最后删除这个临时文件。
unlink($tempfilename);
?>
Static page successfully updated!
上面的代码看上去很令人恐怖,其实这只是因为我们在其中包含了大量的注释。删除这些注释。你会看到这段代码其实很简单。
现在,每当我们运行generateindex.php(也就是说通过一个浏览器请求这个页面),就会从index.php生成一个新刷新的index.html。通过将index.php和generateindex.php移动到一个访问有限制的目录,你可以保证只有站点管理者能够更新你的主页。将这个脚本作一下扩充,你可以生成你的站点上的所有的半动态页面,你还可以在你的内容管理系统中增加“更新主页”的连接!
如果你希望你的主页能够自动地刷新,你只需要设置你的服务器定期地运行generateindex.php(例如说,每隔一个小时)。在新的Windows 9x下,你可以使用任务管理程序(对于旧的版本,你必须使用补丁包)每隔一个小时自动运行php.exe。你只需要建立一个包含以下行的名为generateindex.bat的批处理文件。
C:PHPphp.exe C:WWWgenerateindex.php
如果必要的话,对路径和文件名进行调整,然后设置任务管理程序每隔一个小时执行一次generateindex.bat(你需要设置24个每天在固定时间运行的任务)。
在Linux下(或其它基于UNIX的平台下)你可以使用cron--一个可以在各种UNIX系统下用来定义任务和运行时间的程序来完成类似的工作。如果你对cron还不了解的话,你可以请教你熟悉的Linux专家,或者查阅你熟悉的Linux网站。
你使用cron设置任务和我们之前讨论的在Windows下的用法很类似。但是,你需要一个单机版的PHP,这不是指在第一章中编译的Apache中可导入的PHP模块。你需要对用来编译Apache模块的同一软件包中单独地进行编译。如果你需要帮助,你可以参看软件包提供的说明,也可以查阅PHP官方网站!
对于一个有经验的cron使用者来说,你只需要在你的crontab文件中增加下面的这一行:
0 0-23 * * * php /path/to/generateindex.php > /dev/null
处理文件的上载
到目前为止,这个教程中数据库驱动的站点的所有例子都是处理的文本的数据。笑话、文章、作者...所有的这些都可以完全由文本形式的字符串来表示。但是如果你在运行时,有一个在线的数字图库需要人们能够上载用数字照相机拍摄的图片,我们就需要允许访问者向我们的站点上载他们的图片,我们也需要相应的处理程序。
让我们先从基本的开始:写一个HTML表单用来供用户上载文件。在HTML中,这很简单,只需要用一个标志就行了。但是,默认情况是只有用户选择的文件名被发送了。要通过表单数据提交文件自身,我们需要在标志中增加ENCTYPE="multipart/form-data":ENCTYPE="multipart/form-data">
Select file to upload:
正如我们看到的,一个PHP脚本(fileupload.php)会处理前面的表单提交的数据。也正如你所预计的,一个名为$uploadedfile(由标志的NAME属性确定)的PHP变量会自动被建立。但是,$uploadedfile中存储的不是上载文件的内容,而是存储在Web服务器上的硬盘中的文件的文件名,这个文件被保存在TEMP环境变量所指定的目录中(例如,对于绝大多数的Windows 9x系统,这个目录将是C:WindowsTEMP)。这个文件仅仅在用来处理该表单提交的PHP脚本运行时存在,所以如果你想有什么其它用途(例如,将它存起来以供网站显示),你需要使用我们在前面提到的copy函数在其它地方做一份拷贝。
伴随着$uploadedfile,三个其它的变量也会同时被建立。$uploadedfile_name包含了文件提交前的文件名(已提交的文件将在TEMP目录中以phpx的文件名存储,这里x是一个数字),$uploadedfile_size说明了文件的大小(以字节表示),而$uploadedfile_type说明了MIME类型(例如text/plain、image/gif等等)。记住,"uploadedfile"仅仅是提交文件的INPUT标志中的NAME,实际的文件名将存在上述变量中。
你可以根据这些变量以决定是否接受一个上载的文件。例如,在我们的图库中我们仅仅只对JPEG或GIF文件感兴趣。这些文件的MIME类型应该是image/pjpeg或image/gif,所以确认上载文件的代码大致上是这样大:
if ("image/pjpeg" == $uploadedfile_type
or "image/gif" == $uploadedfile_type) {
// Handle the file...
} else {
echo("
Please submit a JPEG or GIF image file. ");
}
虽然你可以使用一个类似的技术以拒绝过大的文件(通过检查$uploadedfile_size变量),但是通常这不是一个好主意。在得到这个变量之前,这个文件已经被上载并保存在TEMP目录中。如果你试图因为磁盘容量或者是带宽的原因拒绝文件的上载,事实上那个大文件还是被上载了(尽管它们立即又被删除了),这对于你来说也许是个问题。
更好的方法是,你可以提前告诉PHP你希望可以接受的文件的大小的上限。有两个方法。第一个是调整你的php.ini文件中的upload_max_filesize设置。默认值是2MB,所以如果你想要接受更大的文件,你需要立即改变这个值。
第二个方法是在你的表单中包含一个隐含INPUT域,它的名字是MAX_FILE_SIZE,在其中你可以定义你所能接受的最大的文件的大小。出于安全的原因,这个值不能超过你的php.ini文件中的upload_max_filesize的设置,但是它提供了一种方法在不同页面中各自定义上载文件大小的上限。例如,下面的表单,只允许我们最大上载1K字节的文件(1024字节):ENCTYPE="multipart/form-data">
Select file to upload:
指定唯一的文件名
正如我们前面提到的,要保存一个上载的文件,我们需要将它拷贝到另一个目录是保存。当我们从$uploadedfile_name获取每个上载的文件的文件名时,我们不能保证不会上传两个同名的文件。在这种情况下,使用它的原名存储文件将导致新上载的文件覆盖原来上载的文件。
因为这个原因,你通过想要采用一种方法对所有上载的文件指定一个唯一的文件名。使用系统时间(它可以通过使用PHP的time函数获得),我们可以容易地取得一个其于从1/1/1970到目前的秒数的名字。但是如果两个文件恰巧在同一秒同时被上载呢?这了防止这个问题,我们在文件名中同时使用客户端的IP地址(由PHP自动存储在$REMOTE_HOST中)。因为我们不太可能同一秒从同一个IP地址接受两个文件,这个方案应该是可行的。
// Pick a file extension
if ( "image/pjpeg" == $uploadedfile_type )
$extension = ".jpg";
else
$extension = ".gif";
// The complete path/filename
$filename = "C:Uploads" . time() .
$REMOTE_HOST . $extension;
// Copy the file
if (copy($uploadedfile, $filename)) {
echo("
File stored successfully as $filename.");
} else {
echo("
Could not save file as $filename!");
}
请注意如果是在Windows下,我们必须在路径中使用双反斜杠(),因为反斜杠用来在PHP文本字符串中表示特殊字符。而在UNIX下,我们只要象通常那样使用一个斜杠(/)。
将上载的文件保存到数据库中
我们已经建立了一个访问者可以上传JPEG和GIF图象,并将其存储在我们的服务器上的系统,但是为什么不是这个教程所介绍的数据库驱动呢?如果我们这个系统就这样维持现状不变,将不得不有人负责从文件夹中收集提交的图象并手工将其添加到Web站点!回头看看第七章,在那里我们开发了一个系统使得站点的访问者可以提交笑话将将其存到数据库中,以备管理者通过,我们知道这是一种更好的方法!
MySQL有一些列类型可以用来存储二进制数据。在数据库术语中,这些列类型可以存储BLOB(二进制大对象)。然而,在一个关系型数据库中储存大的文件并不是一个好主意。尽管将所有数据放在一个地方会给我们带来方便,但是大的文件导致大的数据库,而大的数据库会导致性能的降低和太大的备份文件。
通常最好的选择是将文件名存储在数据库中。只要你记得在数据中删除记录时删除相应的文件就可以了。
PHP中的Email
Email在Internet上有着强大的影响力。不论你是想要给你的用户提供一个"what's new"周刊,还是考虑一个途径让你的用户可以获得丢失的口令,你都会用到email。PHP便得使用email非常的简单,你只需要简单地调用mail函数就可以发出信息。
在你使用mail函数发送email之前,你首先必须设置PHP的与email相关的选项。这儿是在Windows下的php.ini文件中的相关行:
[mail function]
SMTP = localhost ;仅对win32有效
sendmail_from = me@localhost.com ;仅对win32有效
;sendmail_path = ;仅对unix有效 ...
取决于你使用的是Windows还是UNIX,PHP会通过一个SMTP服务器或一个本地的sendmail系统发送email。对这些的设置不是本教程的讨论范围,你可以从其它地方找到有关这二者的大量信息。然而,如果你是在Windows上运行,有可能你的ISP已经为你提供了一个SMTP服务器。这也就是你发送信息设置你的email程序所用的服务器。将SMTP设置为那个服务器的主机名或IP地址。
sendmail_from会设置你的emails发出时默认的发出的email地址。如果你正在管理这个服务器,你可以将你的email地址放在这儿。
最后,sendmail_path在UNIX下将不会被注释(也就是说,删除这一行前面的分号),你需要将其设置为你的系统上的sendmail程序的路径和文件名。在Linux下,这通常是指/usr/sbin/sendmail。
做好这些配置后重新启动你的Web服务器,PHP将具有全部的email功能。现在在PHP中发送一个email是相当容易的:
mail("to-address@somewhere.com", "Message Subject", "This is the body of the message.");
要发送给多个收件人只需要将多个地址用逗号分开:
mail("to1@mail.net, to2@mail.net, ...", "Message Subject", "Message body");
在标题中指定From:或者Reply-To:的地址也非常简单。将其作为第四个参数带入,其中以回车-换行符分隔:
mail("to@mail.net", "Message Subject", "Message body", "From: webmaster@host.com Reply-to:admin@host.com");
与一个数据库相结合,一个邮件列表变得非常容易管理!只需要从数据库中取出地址列表并使用mail函数发送信息就行了。个人化的信息也非常简单。参看下面的例子:
// Retrieve $email and $password from the database based
// on the $username provided in a form.
mail($email, "Your Password",
"Hi there!
You just filled out a form on our Web site
indicating that you had lost your password.
As requested, we are sending it to you by
email.
username: $username
password: $password
Please record this information in a safe
place so you have it on hand for your next
visit to pingpongballs.com!
-The Webmaster.
");
如果你在在UNIX下运行,而且你没有一个本地的sendmail系统可以发送email,这也不要紧。PHP具有完善的TCP/IP网络性能,如果需要,你可以连接到一个SMTP服务器以发送信息。同样的,如果你需要在发出的信息中包含附件,PHP也可以实现这种功能。
不幸的是,内置的mail函数不支持这些特征,如果你需要它们,你将不得不从头编写你自己的email函数。WROX Press编写的"专业PHP程序设计"已经为你完成了这些工作,在该书的第17章你可以找到全部的代码。尽管这是我高度推荐的一本好书(见我的回顾),但是如果你只是想获得这项功能,你也可以不购买这本书,这个源代码你可以从WROX的网站自由地下载。
除了这两个小问题外,PHP的内置mail函数为你的Web页面发送email信息提供了令人难以相信的方便。
本文原创发布php中文网,转载请注明出处,感谢您的尊重!
相关文章:

安卓手机格式化怎么弄_安卓手机无法启动如何进行格式化
当我们在使用安卓智能手机的时候,由于使用错误或者出现的各种问题导致手机无法重启,相信你一定会感到很烦恼!而如果手机混乱到无法启动,格式化是一个不错的尝试方法!下面给大家介绍手机格式化的方法和注意事项…

位域 内存 字节序_JS操作内存?二进制数组了解一下
二进制数组的由来主要是为了提高浏览器与显卡之间的通信效率,由二进制数据代替传统的文本。二进制数组主要有三个对象:ArrayBufferTypedArrayDataViewArrayBuffer对象ArrayBuffer是一个构造函数,参数是一个数字,代表索取多少个字节…

求排列的逆序数(分治)
考虑1,2,…,n (n < 100000)的排列i1,i2,…,in,如果其中存在j,k,满足 j < k 且 ij > ik, 那么就称(ij,ik)是这个排列的一个逆序。 一个排列含有逆序的个数称为这个排列的逆序数。例如排列 263451 含…

mysql 查看当前事务id,MySQL 如何查询当前最新事务ID
写在前面:在个别时候可能需要查看当前最新的事务 ID,以便做一些业务逻辑上的判断(例如利用事务 ID 变化以及前后时差,统计每次事务的响应时长等用途)。通常地,我们有两种方法可以查看当前的事务 ID:1、执行 SHOW ENGIN…

password
pwdText wx.TextCtrl(panel, -1, ”password”, size(175, -1), stylewx.TE_PASSWORD)转载于:https://www.cnblogs.com/chengxuyuan326260/p/6364695.html

java 自带thread分析工具_java自带的jvm分析工具
这段时间觉得很有必要对java的内存分析工具进行熟悉,这样以后出现机器负载较高,或者反应很慢的时候,我就可以查找原因了。上网搜了搜,发现下面这些是比较常用的,然后我在机器上试试了,把结果也贴出来哈。1.…

Python笔记:字典的fromkeys方法创建的初始value同内存地址问题
dict中的fromkeys()函数可以通过一个list来创建一个用同一初始value的dict。 1 d dict.fromkeys(["苹果", "菠萝"], [apple, pineapple]) 2 print(d) 3 d.get("苹果").append(orange) 4 print(d){苹果: [apple, pineapple], 菠萝: [apple, pine…

表格下划线怎么加粗_这招高!Excel签名栏的下划线随列宽变化,是不是感觉牛哄哄的?...
职场牛人的世界总有各种高招,随手蹦出,令人赞叹不已!今天早上去填一个表格,在输入签名时,突然发现签名处的下划线是随着列宽的变化而自动变化,这绝对是动态的,这是怎么做到的呢?我特…

JS高级程序设计拾遗
《JavaScript高级程序设计(第三版)》反反复复看了好多遍了,这次复习作为2017年上半年的最后一次,将所有模糊的、记不清的地方记录下来,方便以后巩固。 0. <script>元素属性 async表示立即下载脚本,但…

mysql建立高效索引,如何知道你建立的MySQL索引是高效,合理的
不管是开发人员,仍是数据库维护人员,给表建立索引是很常见的事情。普通到什么程度,初级,中级开发人员的印象中,只要写的sql语句效率不高,第一反应就是建索引,而无论这个字段是否适合建立索引。反…

32位java 最大内存_【答疑系列】为什么32位系统只支持最大4G内存?
这个问题一直都有同学问到,算是提问次数最多的问题之一了。32位是什么现在主流的操作系统都是64位的,早期存在32位操作系统,相信大家也都有所听闻,其实,在更早之前,还有16位、8位的,这里就不展开…

新手C#string类常用函数的学习2018.08.04
ToLower()用于将字符串变为小写,注意字符串的不可变特性,需要重新赋值给另一个字符串变量。 s s.ToLower();//字符串具有不可变性,转换后需要重新赋值,不可仅有s.ToLower(); 这可以使用户的输入不区分大小写,例如验证…

开始使用博客了,改变从这里开始。
开始使用博客了,改变从这里开始。 开始使用博客了,改变从这里开始。 开始使用博客了,改变从这里开始。转载于:https://www.cnblogs.com/hello001/p/6367259.html

php 贝瑟尔曲线,贝塞尔曲线的应用详解
简介贝塞尔曲线是可以做出很多复杂的效果来的,比如弹跳球的复杂动画效果,首先加速下降,停止,然后弹起时逐渐减速的效果。使用贝塞尔曲线常用的两个网址如下:缓动函数:cubic-bezier:如何用贝塞尔…

区别 eks_sport 和 exercise 有什么区别?看完你就清楚了!
说到“运动”sport 这个单词应该是不少人看到“运动”的第一反应吧sport /spɔ:t/ n.体育运动例如:Id say football is my favourite sport.我最喜欢的运动要数足球了。习语:be a sport 讲交情例如:Shes a good sport.她很讲交情。sport通常指…

java gps时间转换工具_java 时间戳和时间互转工具 和 时间偏移量计算
时间互转代码片段:* 时间戳 转 时间 ** param beginDate* return* see [类、类#方法、类#成员]*/public static String timeStampToTime(String beginDate){SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date new Date(Long…

tcp 状态转换.
命令行:rootubuntu:/home/linson# netstat -apt | grep 3030 server,listen 服务端根据端口生成一个socket.用于监听连接.也就是监听3次握手,当3次握手成功,建立一个连接接放入队列中. 也就是说执行了listen,会自动应答3次握手,如果不执行listen,没有api会帮你处理3次握手. 所以…

增加、修改、删除
第一;,models.py建表 from django.db import models# Create your models here.class Book(models.Model): #必须继承models.Model这个类,jango才能识别Book是一张表namemodels.CharField(max_length20)#charfield字符串类型,长度20#pricemodels.FloatFi…

java ee 笔试题目,JSP经典笔试@题目(含答案)
JSP经典笔试题目(含答案)更新时间:2017/2/5 19:25:00 浏览量:557 手机版JSP综合测试笔试1)在Java EE中,Servlet是在服务器端运行,以处理客户端请求而做出的响应的程序,下列选项中属于Servlet生命周期阶段的是( )A.加…

句法依存分析_[NLP学习笔记]句法分析
句法分析任务简介成分句法分析(Constituency Parsing):分析句子的成分,给出一棵树由终结符和非终结符构成的句法树。依存句法分析(Dependency Parsing):分析句子中词与词之间的依存关系…

modifiers在JAVA中_Java Modifier.classModifiers方法代碼示例
import java.lang.reflect.Modifier; //導入方法依賴的package包/類/*** Returns a string describing this {code Class}, including* information about modifiers and type parameters.** The string is formatted as a list of type modifiers, if any,* followed by the k…

华为笔试题---明明的随机数
题目 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不…

扩展城市信道etu模型matlab仿真,LTE System Toolbox:无线通信系统的仿真、分析和测试...
LTE System Toolbox 提供用于设计、仿真和验证 LTE 和 LTE-Advanced 通信系统且符合标准的函数和应用程序。该系统工具箱加速了 LTE 算法和物理层 (PHY) 部署,支持黄金参考验证和一致性测试,并能够生成测试波形。借助该系统工具箱,您可以配置…
i/o多路复用笔记
1、用户空间和内核空间 操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也可以访问底层硬件设备。为了保护用户进程不能直接操作内核,保证内核的安全,操作系统将虚拟空间划分为两部分࿰…

接口有个电池标志_USB接口上的小标签有啥用?从“+”号到闪电的奥秘
你有注意过自己PC,尤其是笔记本USB接口上面的小符号了吗?从“”号到闪电,小狮子前几天移动硬盘接驳始终没反应的时候,各种切换完毕发现这似乎是一个平时很少注意的细节啊……从“”号开始谈起仔细端详PC USB接口的时候会发现&…

java arraylist优点_Java中各种集合的特点总结
1:集合:(1) Collection(单列集合)List(有序,可重复)ArrayList底层数据结构是数组,查询快,增删慢线程不安全,效率高Vector底层数据结构是数组,查询快,增删慢线程安全,效率低LinkedList底层数据结构是链表,查询慢,增删快线程不安全,效率高Set(无序,唯一)HashSet底层数…

mysql主从结构主数据库_mysql主从结构主数据库
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里云数据库专家保驾护航,为用户…

JZOJ 5461 购物 —— 贪心
题目:https://jzoj.net/senior/#main/show/5461 贪心,原来想了个思路,优先选优惠价最小的 K 个,然后其他按原价排序遍历; 如果当前物品没选过,原价选上,如果选过,考虑把它换成原价&a…

matlab中的expotest,提高Fortran矩阵指数性能(Expokit比Matlab、Python慢)
我正在进行一个模拟,其中的瓶颈是执行大量复杂的双精度矩阵指数运算,我发现Fortran(Expokit)对于小矩阵很好,但对于较大的矩阵,它的性能比Matlab或Python差。在我在下面包含了一个显示类似行为的模型程序,尽管它需要更…

Win7下使用Putty代替超级终端通过COM串口连接开发板方法
1、如果电脑(笔记本)没有串口接口,则需要使用一个 USB-Serial 转换线,这里使用 prolific usb-serial USB--串口转换线,首先需要在win7上安装对应的 USB--串口转换线 驱动程序,PL2303_Prolific 驱动程序下载…