首页 » 网站推广 » php写日记换行技巧_PHP理论常识之洗澡更衣重看PHP根本二

php写日记换行技巧_PHP理论常识之洗澡更衣重看PHP根本二

访客 2024-12-13 0

扫一扫用手机浏览

文章目录 [+]

八、标准

PHP组件和框架的数量很多,随之产生的问题便是:单独开拓的框架没有考虑到与其他框架的通信。
这样对开拓者和框架本身都是不利的。

冲破旧局势的PHP-FIG

php写日记换行技巧_PHP理论常识之洗澡更衣重看PHP根本二

多位PHP框架的开拓者认识到了这个问题,在2009年的 php|tek(一个受欢迎的PHP会议)上评论辩论了这个问题。
经由谈论后得出:我们须要一个标准,用来提高框架的互操作性。
于是这几位在php|tek意外碰头的PHP框架开拓者组织了PHP Framework Interop Group,简称PHP-FIG。

php写日记换行技巧_PHP理论常识之洗澡更衣重看PHP根本二
(图片来自网络侵删)

PHP-FIG是框架代表自发组织的,其成员不是选举产生的,任何人都可以申请加入PHP-FIG,并且能对处于发起阶段的推举规范提交反馈。
其余,PHP-FIG发布的是推举规范,而不是逼迫规定。

PSR是什么?

PSR是PHP Standards Recommendation(PHP推举标准)的简称。
截至今日,PHP-FIG发布了五个推举规范:

PSR-1:基本的代码风格PSR-2:严格的代码风格PSR-3:日志记录器接口PSR-4:自动加载

你会创造只有四个,没错,由于第一份推举规范PSR-0废弃了,新发布的PSR-4替代了。

PSR-1:基本的代码风格

如果想编写符合社区标准的PHP代码,首先要遵守PSR-1。
遵守这个标准非常大略,可能你已经再利用了。
标准的细节就不写啦,点链接就能看。

PSR-2:严格的代码风格

PSR-2是在PSR-1的根本上更进一步的定义PHP代码规范。
这个标准办理了很多世纪问题哈,比如缩进,大括号等等。
细节也不多记录啦。

其余,现在很多IDE(比如,PHPStorm)会有代码格式化功能,设置代码格式化的标准,编写完代码,然后全部格式化,可以帮助你遵照推举规范,修复一些换行、缩进、大括号等细节。

PSR-3:日志记录器接口

这个推举规范与前两个不同,这是一个接口,规定PHP日志记录器组件可以实现的方法。
符合PSR-3推举规范的PHP日志记录器组件,必须包含一个实现Psr\Log\LoggerInterface接口的PHP类。
PSR-3接口复用了RFC 5424系统日志协议,规定要实现的九个方法:

<?phpnamespace Psr\Log;interface LoggerInterface{ public function emergency($message, array $context = array()); public function alert($message, array $context = array()); public function critical($message, array $context = array()); public function error($message, array $context = array()); public function warning($message, array $context = array()); public function notice($message, array $context = array()); public function info($message, array $context = array()); public function debug($message, array $context = array()); public function log($level, $message, array $context = array());}

每个方法对应RFC 5424协议的一个日志级别。

利用PRS-3日志记录器

如果你正在编写自己的PSR-3日志记录器,可以停下来了。
由于已经有一些十分出色的日志记录器组件。
比如:monolog/monolog,直接用就可以了。
如果不能知足哀求,也建议在此根本上做扩展。

PSR-4:自动加载器

这个推举规范描述了一个标准的自动加载器策略。
自动加载器策略是指,在运行时按需查找PHP类,接口或性状,并将其载入PHP阐明器。

为什么自动加载很主要

在PHP文件的顶部你是不是常常看到类似下面的代码?

<?phpinclude 'path/to/file1.php';include 'path/to/file2.php';include 'path/to/file3.php';

如果只需载入几个PHP脚本,利用这些函数(include()、include_once()、require()、require_once())能很好的完成事情。
可是如果你要引入一千个PHP脚本呢?

在PSR-4推举规范之前,PHP组件和框架的作者利用__autoload()和spl_autoload_register()函数注册自定义的自动加载器策略。
可是,每个PHP组件和框架的自动加载器都利用独特的自动加载器。
因此,利用的组件多的时候,也是很麻烦的事情。

推举利用PSR-4自动加载器规范,便是办理这个问题,促进组件实现互操作性。

PSR-4自动加载器策略

PSR-4推举规范不哀求改变代码的实现办法,只建议如何利用文件系统目录构造和PHP命名空间组织代码。
PSR-4的精髓是把命名空间的前缀和文件系统中的目录对应起来。
比如,我可以见告PHP,\Oreilly\ModernPHP命名空间中的类、接口和性状在物理文件系统的src/目录中,这样PHP就知道,前缀为\Oreilly\ModernPHP的命名空间中的类、接口和性状对应的src/目录里的目录和文件。

如何编写PSR-4自动加载器

如果你在写自己的PSR-4自动加载器,请停下来。
我们可以利用依赖管理器Composer自动天生的PSR-4自动加载器。

九、过滤HTML

利用htmlentities()函数过滤输入。

<?php$input = '<p><script>alert(\"大众You won the Nigerian lottery!\"大众);</script></p>';echo htmlentities($input, ENT_QUOTES, 'UTF-8');

须要把稳的是:默认情形下,htmlentities()函数不会转义单引号,而且也检测不出输入字符串的字符集。
精确的利用办法是:第一个参数输入字符串;第二个参数设为ENT_QUOTES常量,转移单引号;第三个参数设为输入字符串的字符集。

更多过滤HTML输入的办法,可以利用HTML Purifier库。
这个库强健且安全,缺陷:慢,且可能难以配置。

十、SQL查询

构建SQL查询不好的办法:

$sql = sprintf( 'UPDATE users SET password = \"大众%s\公众 WHERE id = %s', $_POST['password'], $_GET['id']);

如果 psasword=abc\"大众;-- ,则导致修正了全体users表的记录password都未abc。
如果须要在SQL查询中利用输入数据,要利用PDO预处理语句。

十一、用户资料信息

A.过滤用户资料中的电子邮件地址

这里会删除除字符、数字和!#$%&'+-/=?^_{|}~@.[]`之外的所有其他符号。

<?php$email = 'beckjiang@meijiabang.cn';$emailSafe = filter_var($email, FILTER_SANITIZE_EMAIL);

B.过滤用户资料中的外国字符

<?php$string = \"大众外国字符\公众;$safeString = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW|FILTER_FLAG_ENCODE_HIGH);十二、验证数据

验证数据与过滤不同,验证不会从输入数据中删除信息,而是只确认输入数据是否符合预期。

1、验证电子邮件地址

我们可以把某个FILTER_VALIDATE_标志传给filter_var()函数,除了电子邮件地址,还可以验证布尔值、浮点数、整数、IP地址、正则表达式和URL。

<?php$input = 'beckjiang@meijiabang.cn';$isEmail = filter_var($input, FILTER_VALIDAE_EMAIL);if ($isEmail !== false) { echo \"大众Success\"大众;} else { echo \"大众Fail\"大众;}

2、密码

哈希算法有很多种,例如:MD5、SHA1、bcrypt和scrypt。
有些算法的速率很快,用于验证数据完全性;有些算法速率则很慢,旨在提高安全性。
天生密码和存储密码时须要利用速率慢、安全性高的算法。

目前,经同行审查,最安全的哈希算法是bcrypt。
与MD5和SHA1不同,bcrypt是故意设计的很慢。
bcrypt算法会自动加盐,防止潜在的彩虹表攻击。
bcrypt算法永不过时,如果打算机的运算速率变快了,我们只需提高事情因子的值。

重新打算密码的哈希值

下面是登任命户的脚本:

<?phpsession_start();try { // 从要求主体中获取电子邮件地址 $email = filter_input(INPUT_POST, 'email'); // 从要求主体中获取密码 $password = filter_input(INPUT_POST, 'password'); // 利用电子邮件地址获取用户(把稳,这是虚构代码) $user = User::findByEmail($email); // 验证密码和账户的密码哈希值是否匹配 if (password_verify($password, $user->password_hash) === false) { throw new Exception('Invalid password'); } // 如果须要,重新打算密码的哈希值 $currentHashAlgorithm = PASSWORD_DEFAULT; $currentHashOptions = array('cost' => 15); $passwordNeedRehash = password_needs_rehash( $user->password_hash, $currentHashAlgorithm, $currentHashOptions ); if ($passwordNeedsRehash === true) { // 保存新打算得出的密码哈希值(把稳,这是虚构代码) $user->password_hash = password_hash( $password, $currentHashAlgorithm, $currentHashOptions ); $user->save(); } // 把登录状态保存到回话中 ... // 重定向到个人资料页面 ...} catch (Exception $e) { //非常处理 ...}

值得把稳的是:在登录前,一定要利用password_needs_rehash()函数检讨用户记录中现有的密码哈希值是否过期。
如果过期了,要重新打算密码哈希值。

PHP5.5.0之前的密码哈希API

如果无法利用PHP5.5.0或以上版本,可以利用安东尼·费拉拉开拓的ircmaxell/password-compat组件。
这个组件实现了PHP密码哈希API中的所有函数:

password_hash()password_get_info()password_needs_rehash()password_verify()十三、DateTime类

DateTime类供应一个面向工具接口,用于管理日期和韶光。

没有参数,创建的是一个表示当前日期和韶光的实例:

<?php$datetime = new DateTime();

传入参数创建实例:

<?php$datetime = new DateTime('2017-01-28 15:27');

指定格式,静态布局:

<?php$datetime = DateTime::createFromFormat('M j, Y H:i:s', 'Jan 2, 2017 15:27:30');十四、DateInterval类

DateInterval实例表示长度固定的韶光段(比如,“两天”),或者相对而言的韶光段(比如,“昨天”)。
DateInterval实例用于修正DateTime实例。

利用DateInterval类:

<?php// 创建DateTime实例$datetime = new DateTime();// 创建长度为两周的间隔$interval = new DateInterval('P2W');// 修正DateTime实例$datetime->add($interval);echo $datetime->format('Y-m-d H:i:s');

创建反向的DateInterval实例:

<?php// 过去一天$interval = new DateInterval('-1 day');十五、DateTimeZone类

如果运用要迎合国际客户,可能要和时区斗争。

创建、利用时区:

<?php$timezone = new DateTimeZone('America/New_York');$datetime = new DateTime('2017-01-28', $timezone);

实例化之后,也可以利用setTimeZone()函数设置市区:

$datetime->setTimeZone(new DateTimeZone('Asia/Hong_Kong'));十六、DatePeriod类

有时我们须要迭代处理一段韶光内反复涌现的一系列日期和韶光,DatePeriod类可以办理这种问题。
DatePeriod类的布局方法接管三个参数,而且都必须供应:

一个Datetime实例,表示迭代开始时的日期和韶光。
一个DateInterval实例,表示到下个日期和韶光的间隔。
一个整数,表示迭代的总次数。

DatePeriod实例是迭代器,每次迭代时都会产出一个DateTime实例。

利用DatePeriod类:

<?php$start = new DateTime();$interval = new DateInterval('P2W');$period = new DatePeriod($start, $interval, 3);foreach ($period as $nextDateTime) { echo $nextDateTime->format('Y-m-d H:i:s'), PHP_EOL;}十七、流

在当代的PHP特性中,流或许是最出色但最少利用的。
虽然PHP4.3.0就引入了流,但很多开拓者不知道流的存在,由于很少人提及流,而且流的文档也匮乏。
官方的阐明比较难明得,一句话说便是:流的浸染是在出发地和目的地之间传输数据。

我把流理解为管道,相称于把水从一个地方引到另一个地方。
在水从出发地流到目的地的过程中,我们可以过滤水,可以改变水质,可以添加水,也可以排出水(提示:水是数据的隐喻)。

流封装协议

流式数据的种类互异,每种类型须要独特的协议,以便读写数据。
我们称这些协议为流封装协议。
比如,我们可以读写文件系统,可以通过HTTP、HTTPS或SSH与远程Web做事器通信,还可以打开并读写ZIP、RAR或PHAR压缩文件。
这些通信办法都包含下述相同的过程:

开始通信。
读取数据。
写入数据。
结束通信。

虽然过程一样的,但是读写文件系统中文件的办法与手腕HTTP的办法有所不同。
流封装协议的浸染是利用通用的几口封装这些差异。

每个流都有一个协议和一个目标。
格式如下:

<scheme>://<target>

说这么多有点懵,先看例子,利用HTTP流封装协议与Flickr API通信:

<?php$json = file_get_contents( 'http://api.flickr.com/services/feeds/photos_public.gne?format=json');

不要误以为这是普通的网页URL,file_get_contents()函数的字符串参数实在是一个流标识符。
http协议会让PHP利用HTTP流封装协议。
看起来像是普通的网页URL,是由于HTTP流封装协议便是这样规定的:)。
其他流封装协议可能不是这样。

file://流封装协议

我们利用file_get_contents(),fopen(),fwrite()和fclose()函数读写文件系统。
由于PHP默认利用的流封装协议是file://,以是我们很少认为这些函数利用的是PHP流。

隐式利用file://流封装协议:

<?php$handle = fopen('/etc/hosts', 'rb');while (feof($handle) !== true) { echo fgets($handle);}fclose($handle);

显式利用file://流封装协议:

<?php$handle = fopen('file:///etc/hosts', 'rb');while (feof($handle) !== true) { echo fgets($handle);}fclose($handle);

流高下文

有些PHP流能接管一些列可选的参数,这些参数叫流高下文,用于定制流的行为。
流高下文利用stream_context_create()函数创建。

比如,你知道可以利用file_get_contents()函数发送HTTP POST要求吗?如果想这么做,可以利用一个流高下文工具:

<?php$requestBody = '{\"大众username\"大众: \"大众beck\"大众}';$context = stream_context_create(array( 'http' => array( 'method' => 'POST', 'header' => \公众Content-Type: application/json;charset=utf-8;\r\n\"大众 . \"大众Content-Length: \公众 . mb_strlen($requestBody), \公众content\公众 => $requestBody )));$response = file_get_contents('https://my-api.com/users', false, $context);

流过滤器

关于PHP的流,实在真正强大的地方在于过滤、转换、添加或删除流中传输的数据。

把稳:PHP内置了几个流过滤器:string.rot13、string.toupper、string.tolower和string.strp_tags。
这些过滤器没什么用,我们要利用自定义的过滤器。

若想把过滤器附加到现有的流上,要利用stream_filter_append()函数。
比如,想要把文件中的内容转换成大写字母,可以利用string.toupper过滤器。
书中不建议利用这个过滤器,这里只是演示如何把过滤器附加到流上:

<?php$handle = fopen('data.txt', 'rb');stream_filter_append($handle, 'string.toupper');while (feof($handle) !== true) { echo fgets($handle); // <-- 输出的全是大写字母}fclose($handle);

利用php://filter流封装协议把过滤器附加到流上:

<?php$handle = fopen('php://filter/read=string.toupper/resource=data.txt', 'rb');while (feof($handle) !== true) { echo fgets($handle); // <-- 输出的全是大写字母}fclose($handle);

来看个更实际的流过滤器示例,如果我们nginx访问日志保存在rsync.net,一天的访问情形保存在一个日志文件中,而且会利用bzip2压缩每个日志文件,名称格式为:YYYY-MM-DD.log.bz2。
某天,领导让我提取过去30天某个域名的访问数据。
利用DateTime类和流过滤器迭代bzip压缩的日志文件:

<?php$dateStart = new \DateTime();$dateInterval = \DateInterval::createFromDateString('-1 day');$datePeriod = new \DatePeriod($dateStart, $dateInterval, 30);//创建迭代器foreach ($datePeriod as $date) { $file = 'sftp://USER:PASS@rsync.net/' . $date->format('Y-m-d') . 'log.bz2'; if (file_exists($file)) { $handle = fopen($file, 'rb'); stream_filter_append($handle, 'bzip2.decompress'); while (feof($handle) !== true) { $line = fgets($handle); if (strpos($line, 'www.example.com') !== false) { fwrite(STDOUT, $line); } } fclose($handle); }}

打算日期范围,确定日志文件的名称,通过FTP连接rsync.net,下载文件,解压缩文件,逐行迭代每个文件,把相应的行提取出来,然后把访问数据写入一个输出目标。
利用PHP流,不到20行代码就能做完所有这些事情。

自定义流过滤器

实在大多数情形下都要利用自定义的流过滤器。
自定义的流过滤器是个PHP类,继续内置的php_user_filter类。
这个类必须实现filter()、onCreate()和onClose()方法。
而且,必须利用stream_filter_register()函数注册自定义的流过滤器。

PHP流会把数据分成按次序排列的桶,一个桶中盛放的流数据量是固定的。
一定韶光内过滤器吸收到的桶叫做桶行列步队。
桶行列步队中的每个桶工具都有两个公开属性:data和datalen,分别是桶中的内容和内容的长度。

下面定义一个处理脏字的流过滤器:

<?phpclass DirtyWordsFilter extends php_user_filter{ / @param resource $in 流来的桶行列步队 @param resource $out 流走的桶行列步队 @param resource $consumed 处理的字节数 @param resource $closing 是流中末了一个桶行列步队吗? / public function filter() { $words = array('grime', 'dirt', 'grease'); $wordData = array(); foreach ($words as $word) { $replacement = array_fill(0, mb_strlen($word), ''); $wordData[$word] = implode(' ', $replacement); } $bad = array_keys($wordData); $goods = array_values($wordData); // 迭代流来的桶行列步队中的每个桶 while ($bucket = stream_bucket_make_writeable($in)) { // 审查桶数据中的脏字 $bucket->data = str_replace($bad, $goods, $bucket->data); // 增加已处理的数据量 $consumed += $bucket->datalen; // 把桶放入流向下贱的行列步队中 stream_bucket_append($out, $bucket); } return PSFS_PASS_ON; }}

filter()方法的浸染是接管、处理再转运桶中的流数据。
这个方法的返回值是PSFS_PASS_ON常量,表示操作成功。

注册流过滤器

接着,我们必须利用stream_filter_register()函数注册这个自定义的DirtWordsFilter流过滤器:

<?phpstream_filter_register('dirty_words_filter', 'DirtWordsFilter');

第一个参数是用于识别这个自定义过滤器的过滤器名,第二个参数是自定义过滤器的类名。

利用DirtWordsFilter流过滤器

<?php$handle = fopen('data.txt', 'rb');stream_filter_append($handle, 'dirty_words_filter');while (feof($handle) !== true) { echo fgets($handle); // <-- 输出审查后的文本}fclose($handle);十八、缺点与非常

对缺点和非常的处理,一定要遵守四个规则:

一定要让PHP报告缺点。
在开拓环境中要显示缺点。
在生产环境中不能显示缺点。
在开拓环境和生产环境中都要记录缺点。
标签:

相关文章

php反射工场技巧_php反射机制用法详解

面向工具编程中工具被授予了自省的能力,而这个自省的过程便是反射。反射,直不雅观理解便是根据到达地找到出发地和来源。比如,一个光秃秃...

网站推广 2024-12-14 阅读0 评论0

php清空body技巧_MySQL 删除数据库

利用普通用户上岸mysql做事器,你可能须要特定的权限来创建或者删除 MySQL 数据库。 以是我们这边利用root用户登录,ro...

网站推广 2024-12-14 阅读0 评论0

windowsphpmail技巧_PHP Mail 函数

mail( 函数许可您从脚本中直接发送电子邮件。需求要使邮件函数可用,PHP 须要已安装且正在运行的邮件系统。要利用的程序是由...

网站推广 2024-12-14 阅读0 评论0