PHP开发要点与技巧总结(二)
- 1 == 'a'、0 == 'a'、97 == '97a'?这里边牵涉到的是默认数据类型转换。
// 无输出 if ('0') { echo "'0' is true\n"; } //'a' is true if ('a') { echo "'a' is true\n"; } // 无输出 if (1 == 'a') { echo "1 == 'a' is true\n"; } //0 == 'a' is true if (0 == 'a') { echo "0 == 'a' is true\n"; } //97 == '97a' is true if (97 == '97a') { echo "97 == '97a' is true\n"; }
- 多次 ++ 与 -- :
$n = 5;
- count / strlen / mb_strlen :count用于统计数组元素或对象属性个数,但不能用于字串长度统计(否则总是返回1);strlen用于获取字符串字节长度,而非字符数;mb_strlen获取多字节编码字符串的长度。
- mysqlnd:当使用mysqlnd而非libmysqlclient作为MySQL客户端库时,buffered queries是默认模式;故要使用unbuffered queries模式,无论使用mysqli、pdo_mysql、mysql三种中的任何一种API都要手动开启,特别是做大数据集查询的时候。
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $uresult = $pdo->query("SELECT Name FROM City"); if ($uresult) { while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { echo $row['Name'] . PHP_EOL; } }
Zend Guard:用于对PHP代码加密与混淆,服务端需要安装Zend Guard Loader库来解密。在Ubuntu 64位系统上还需要安装 lib32z1、libglu1-mesa两个库
sudo apt-get install lib32z1 libglu1-mesa:i386
OpenSSL对称加密: openssl 1.0.1版本后,运行时期自动检测是否支持 AES-NI (Advanced Encryption Standard New Instructions,基本上2010年之后的Intel CPU都支持,另外AMD和ARM的一些型号也支持)。查看处理器是否支持 AES-NI 执行 cat /proc/cpuinfo | grep aes | wc -l
1) OpenSSL采用PKCS7 CBC填充,而mcrypt无填充。2)OpenSSL AES-256相当于MCRYPT_RIJNDAEL_128(32位key),但mcrypt已被废弃。3)先加密,后认证(Message Authenticity,HMAC),防止被篡改的消息仍然被解密。4)AES-128、AES-192、AES-256密钥长度分别是128、192、256位,AES-128和AES-256加密处理轮数分别是10、14轮。5)AES基于数据块(16字节,不足则填充)加密,包括ECB(Electronic Code Book,电子密码本)、CBC(Cipher Block Chaining,加密块链)、CFB(Cipher FeedBack,加密反馈)、OFB(Output FeedBack,输出反馈)、CTR(Counter,计数)五种加密模式。6)在OpenSSL模块中有三种资源类型:第一种是一个 pkey(公钥或私钥)标识符,第二种是一个X509证书标识符,第三种是 CSR (证书签名请求) 标识符。OPENSSL_ZERO_PADDING、OPENSSL_NO_PADDING选项不能用于CBC、CTR。7)AES-256-CBC vs AES-256-CTR:CTR加解密均可并行,CBC解密可并行;CTR能避免Padding Oracle Attacks。8)OpenSSL与JAVA AES/ECB/PKCS5Padding问题:https://blog.csdn.net/kikajack/article/details/79273612。9)Java AES/ECB/PCKS5Padding:
<?php class Aes { public $method = 'AES-128-ECB'; private $key; public function __construct($key) { $this->key = substr(openssl_digest(openssl_digest($key, 'sha1', true), 'sha1', true), 0, 16); } /** * 密文解密 * @return string */ public function decrypt($content) { return $this->_pkcs5Unpad(openssl_decrypt($content, $this->method, $this->key, OPENSSL_ZERO_PADDING), 16); } /** * */ public function encrypt($content) { $content = $this->_pkcs5Pad($content, 16); return openssl_encrypt($content, $this->method, $this->key, OPENSSL_ZERO_PADDING); } //PKCS5Padding 补码方式 private function _pkcs5Pad($text, $blockSize) { $pad = $blockSize - (strlen($text) % $blockSize); return $text . str_repeat(chr($pad), $pad); } private function _pkcs5Unpad($text) { $end = substr($text, -1); $last = ord($end); $len = strlen($text) - $last; if (substr($text, $len) == str_repeat($end, $last)) { return substr($text, 0, $len); } return false; } }
- parse_url():解析 URL,返回其组成部分
$url = 'http://username:password@hostname/path?arg=value#anchor'; print_r(parse_url($url)); echo parse_url($url, PHP_URL_PATH); //Array ( [scheme] => http [host] => hostname [user] => username [pass] => password [path] => /path [query] => arg=value [fragment] => anchor ) /path
- parse_str() 与http_build_query():parse_str()将字符串解析成多个变量,http_build_query()生成 URL-encode 之后的请求字符串。
// http_build_query //0=foo&1=bar&2=baz&3=boom&cow=milk&php=hypertext+processor //myvar_0=foo&myvar_1=bar&myvar_2=baz&myvar_3=boom&cow=milk&php=hypertext+processor $data = array('foo', 'bar', 'baz', 'boom', 'cow' => 'milk', 'php' =>'hypertext processor'); echo http_build_query($data) . "\n"; echo http_build_query($data, 'myvar_'); // parse_str $str = "first=value&arr[]=foo+bar&arr[]=baz"; parse_str($str, $output); echo $output['first']; // value echo $output['arr'][0]; // foo bar echo $output['arr'][1]; // baz
- curl:
// 包含响应头信息 curl_setopt($ch, CURLOPT_HEADER, 1); // 将只获取响应头 curl_setopt($ch, CURLOPT_NOBODY, 1); // 重定向,CURLOPT_MAXREDIRS限制最大重定向次数 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);// 返回响应内容而不是直接输出到页面curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- 外部接口编码转换:如从当前编码UTF-8转换为GBK
header("Content-Type: text/html; charset=GBK"); echo mb_convert_encoding($html, 'GBK', 'UTF-8');
- SoapClient::__soapCall 与 SoapClient::__call:__soapCall参数传递方式四值得注意
$client = new SoapClient("some.wsdl"); $params = array('username'=>'name', 'password'=>'secret'); // 方式一: $client->SomeFunction($a, $b, $c); // 方式二: $client->__soapCall("SomeFunction", array($a, $b, $c)); // 方式三: $client->login($params); // 方式四: $client->__soapCall('login', array($params)); // 方式五: call_user_func_array(array($client, 'login'), [$params]);
时间周期比较:
$holder_birthday = date_create('1984-04-28'); // 方式一: $diff = date_diff($holder_birthday, date_create()); // 方式二: $diff = $holder_birthday->diff(date_create()); if ($diff->invert || $diff->y < 18) { $this->errcodeSet('投保人年龄必须大于18周岁!'); return false; }
动态访问对象属性:
$key = 'name'; echo $obj->{$key.'Pro'};
转义字符:转义字符不能以单引号引出,必须以双引号引出。
$this->conf = str_replace("\r\n","\n", $this->conf);
后期静态绑定:
class A { function __construct() { echo self::class . "\n"; echo static::class . "\n"; } } class B extends A { } // A// B$s = new B();
链式包含(include/include_once/require/require_once):链尾到链首的全局作用域是等效的。
1. 当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。 2. 如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。此规则的一个例外是魔术常量,它们是在发生包含之前就已被解析器处理的。
fwrite/fputs: 当 $fwrite=0 时,下列代码可能导致死循环。参考http://php.net/manual/vote-note.php?id=96951&page=function.fwrite&vote=up
// BROKEN function - infinite loop when fwrite() returns 0s function fwrite_stream($fp, $string) { for ($written = 0; $written < strlen($string); $written += $fwrite) { $fwrite = fwrite($fp, substr($string, $written)); if ($fwrite === false) { return $written; } } return $written; }
- Windows PHP版本选择:TS & NTS
- string字串操作:一个由字节组成的数组再加上一个整数指明缓冲区长度。并无如何将字节转换成字符的信息,由程序员来决定。字符串由什么值来组成并无限制;特别的,其值为 0(“NUL bytes”)的字节可以处于字符串任何位置(不过有几个函数,在本手册中被称为非“二进制安全”的,也许会把 NUL 字节之后的数据全都忽略)。
$a = 'fsafsfsfsfsff'; // sa var_dump($a[1] . ${2});
- PHP 函数/语法结构与命名空间:
(1)在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称。 (2)对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。 (3)在用户自定义命名空间中,PHP内核函数可以被重新定义,但语言结构却不行。
- use操作:use常量和函数。
namespace Name\Space { const FOO = 42; function f() { echo __FUNCTION__."\n"; } } namespace Xx { use const Name\Space\FOO; use function Name\Space\f; echo FOO."\n"; f(); }
- 大型整数的标书与存储:Large integers must be specified as strings - otherwise, PHP will coerce them to floats, resulting in a loss of precision.
- 高精度计算:BC Math & GMP
- HEIF / ImageMagick安装:
#安装依赖包(库),不同平台包(库)名可能不同。如果以安装可免,通过yum list installed查看。 yum -y install gcc-c++ libtool pkg-config libjpeg-devel libpng-devel
#安装libde265(HEVC Decoder / h.265),没有安装libx265(libheif的HEVC Encoder)wget https://github.com/strukturag/libde265/archive/frame-parallel.tar.gztar zxvf frame-parallel.tar.gzcd libde265-frame-parallel./autogen.sh./configuremakemake install#sudo ldconfig /usr/local/lib#make uninstall & make distclean
#安装libheifwget https://github.com/strukturag/libheif/archive/master.tar.gztar zxvf master.tar.gzcd libheif-master./autogen.sh#下边这条命令也可以换成 ./configure libde265_CFLAGS='-I/usr/local/include' libde265_LIBS='-lde265'#libde265.pc 所在的目录./configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfigmakemake install#可能需要加载动态库配置/etc/ld.so.conf#sudo ldconfig /usr/local/lib#heif-convert能把heic转换成png、jpg#/usr/local/bin/heif-convert 1.heic 1.jpeg 将报 “Unknown file type in 1.jpeg”错误#/usr/local/bin/heif-convert 1.heic 1.jpg
#安装imagemagickwget http://imagemagick.org/download/ImageMagick.tar.gztar xvzf ImageMagick.tar.gzcd ImageMagick-7.0.8#环境变量(env可查看所有,export/export -n可设置/删除指定环境变量)PKG_CONFIG_PATH的值为libheif.pc所在的目录。如果configure执行发生错误,请查看config.log./configure --disable-openmp PKG_CONFIG_PATH=/usr/local/lib/pkgconfigmakemake install#sudo ldconfig /usr/local/lib#which identify#/usr/local/bin/identify /var/www/public/1.heic #安装PHP imagick扩展 pecl install imagick #php.ini启用扩展 extension=imagick.so #PHP-FPM reload #systemctl restart php-fpm #卸载 #pecl uninstall imagick
$img = new Imagick(); $img->readImage(__DIR__ .'/1.heic'); //$img->resizeImage(320,240,Imagick::FILTER_LANCZOS,1); $img->writeImage(__DIR__ . '/1.jpg'); $img->clear();
isset():检测变量是否已设置并且非 NULL。若使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE。同时要注意的是 null 字符("\0")并不等同于 PHP 的 NULL 常量。 如果一次传入多个参数,那么 isset() 只有在全部参数都以被设置时返回 TRUE 计算过程从左至右,中途遇到没有设置的变量时就会立即停止。
- self类:
<?php class A { public $a = NULL; public function __construct($s) { $this->a = $s; } public function make($s) { return new self($s); } public function dump($obj) { if ($obj instanceof self) { var_dump($this, $obj); } } } $obj = new A('Obj-1'); $obj->dump($obj->make('Obj-2'));
/public/index.php:19: object(A)[1] public 'a' => string 'Obj-1' (length=5) /public/index.php:19: object(A)[2] public 'a' => string 'Obj-2' (length=5)
- private属性不可继承问题:
abstract class RuleAbstraction { // 匹配模式 private $pattern = null; // 校验对象 private $subject = null; public function setSubject($subject) { $this->subject = $subject; } }
class Email extends RuleAbstraction { // E-mail正则匹配模式 private $pattern = '/^(?!_|-)(?>[\w\.-]+)@(?!-)(?>((?>[a-zA-Z0-9-]+)\.)+)[a-zA-Z]{2,46}$/'; /** * 校验EMail地址 * * @return false|int */ public function check() { var_dump($this); return preg_match($this->pattern, $this->subject); } }
$obj = new Email(); $obj->setSubject('shuznhi.chen@anlaa.com');
var_dump:
object(RuleEngine\Rules\Email)#9 (3) { ["pattern":"RuleEngine\Rules\Email":private]=> string(69) "/^(?!_|-)(?>[\w\.-]+)@(?!-)(?>((?>[a-zA-Z0-9-]+)\.)+)[a-zA-Z]{2,46}$/" ["subject":"RuleEngine\Rules\RuleAbstraction":private]=> string(22) "w12.a/qe_@124afasf.com" ["pattern":"RuleEngine\Rules\RuleAbstraction":private]=> NULL } object(RuleEngine\Rules\Email)#14 (3) { ["pattern":"RuleEngine\Rules\Email":private]=> string(69) "/^(?!_|-)(?>[\w\.-]+)@(?!-)(?>((?>[a-zA-Z0-9-]+)\.)+)[a-zA-Z]{2,46}$/" ["subject":"RuleEngine\Rules\RuleAbstraction":private]=> string(22) "shunzhi.chen@anlaa.com" ["pattern":"RuleEngine\Rules\RuleAbstraction":private]=> NULL }
- fmod():回被除数(
x
)除以除数(y
)所得的浮点数余数。$x = 5.7; $y = 1.3; $r = fmod($x, $y); // $r equals 0.5, because 4 * 1.3 + 0.5 = 5.7
$mod = gmp_mod("8", "3"); echo gmp_strval($mod) . "\n";// 2
PHP开发要点与技巧总结(二)的更多相关文章
- PHP开发要点与技巧总结(一)
Opcache:Opcache 来源于Zend Optimizer+改名,主要作用是通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是省去了每次加载 ...
- Visual Studio 原生开发的10个调试技巧(二)
原文:Visual Studio 原生开发的10个调试技巧(二) 我以前关于 Visual Studio 调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原 ...
- Visual Studio原生开发的10个调试技巧(二)
来源:oschina 发布时间:2013-08-10 阅读次数:397 51 我以前关于Visual Studio调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你 ...
- (转)Visual Studio原生开发的10个调试技巧(二)
我以前关于Visual Studio调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识.以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号).这些技巧可以应用在VS200 ...
- Android开发——ListView使用技巧总结(二)
0. 前言 Android中的ListView是用的比较多的控件之一,在上一篇Android开发--ListView使用技巧总结(一)中对ListView的ViewHolder机制.优化卡顿方式以及 ...
- 一文看懂汽车电子ECU bootloader工作原理及开发要点
随着半导体技术的不断进步(按照摩尔定律),MCU内部集成的逻辑功能外设越来越多,存储器也越来越大.消费者对于汽车节能(经济和法规对排放的要求)型.舒适性.互联性.安全性(功能安全和信息安全)的要求越来 ...
- Android开发——ListView使用技巧总结(一)
)还有一点就是要控制异步任务的执行频率,因为当用户频繁的上下滑动,会瞬间产生上百个异步任务,会带来无意义的大量的UI更新操作,因此可以考虑在列表滑动时停止进行异步任务,直到列表停下来. //判断列表的 ...
- Delphi开发的一些技巧
[Delphi]Delphi开发的一些技巧 一.提高查询效率先进行准备查询操作: CustomerQuery.Close; if not (CustomerQuery.Prepared) then - ...
- WordPress 网站开发“微信小程序“实战(二)
原文链接:https://devework.com/wordpres...,转载请用明链注明来源,谢谢! 本文是"WordPress 开发微信小程序"系列的第二篇,本文记录的是开发 ...
随机推荐
- Java中的守护线程
守护线程的概念 在java中有两种线程,守护线程和非守护线程,其两者并没有本质的区别,唯一的区别就是当前的用户线程退出的时候,若只存在唯一的A线程,若A线程为守护线程,那么JVM将会直接退出,否则JV ...
- Java数据解析之JSON
文章大纲 一.JSON介绍二.常见框架介绍与实战三.Studio中GsonFormat插件使用四.项目源码下载(含参考资料)五.参考文档 一.JSON介绍 1. 简介 JSON 的全称是 Ja ...
- 导入虚拟机vmware,此主机支持Intel VT-x,但Intel VT-x处于禁用状态和黑屏
解决方法:进入BIOS(按什么键进入bios,需要看你用什么电脑),把Intel Virtualization Technology 设置enabled 然后是黑屏解决方法:管理员模式 ...
- RAID5当一块硬盘离线后处理
RAID5当一块硬盘离线后,处理降级状态,这时候正常的建议是马上更换硬盘做REBUILD以恢复完整的数据状态,如果有热备盘的话,就会自动做REBUILD,这样做合适吗? 一组RAID卷在工作很长时间以 ...
- mssql sqlserver with cte表达式(递归)找出最顶值的方法分享
摘要: 下文通过递归的方式找出最顶级部门的方法分享,如下所示: 实验环境:sql server 2008 R2 下文通过cte-with表达式实现递归,获取一个公司的顶级部门,如下所示 例:部门表 c ...
- qt5.11.2+vs2017环境下配置pcl1.8.1以及第三方依赖库vtk的编译
1.准备工作 我所用的开发环境是win10下的qt5.11.2配置了vs2017的编译器,根据自己所用的VS的版本去官网下载对应版本的pcl库,如下 PCL-1.8.1-AllInOne-msvc20 ...
- wordpress如何利用插件添加优酷土豆等视频到自己的博客上
wordpress有时候需要添加优酷.土豆等网站的视频到自己的博客上,传统的分享方法不能符合电脑端和手机端屏幕大小的需求,又比较繁琐,怎样利用插件的方法进行添加呢,本视频向你介绍一款这样的插件——Sm ...
- CentOS 7 最小安装网络配置
通常最小安装是没有自动启动网络连接的,可以通过ifconfig或ip addr查看网络信息 (类似windows里的ipconfig),然而最小安装是没有ifconfig命令的, 这里我们使用ip a ...
- MyBatis学习日记(三):戏说MyBatis配置文件
properties标签 properties标签可以用来加载别的配置文件,比如可以加载数据库的配置文件,jdbc.properties. 下面是jdbc.properties jdbc.driver ...
- 毕业设计(1)基于MicroPython的大棚监测控制系统的程序设计与模型设计
智慧农业就是将物联网技术运用到传统农业中去,运用传感器和软件通过移动平台或者电脑平台对农业生产进行控制,使传统农业更具有“智慧”.除了精准感知.控制与决策管理外,从广泛意义上讲,智慧农业还包括农业电子 ...