首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
183 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
31
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-08-08
2013PHP技术峰会《Bug Free的PHP开发实践分享》摘录
2013PHP技术峰会《Bug Free的PHP开发实践分享》摘录上次参加了2013PHP技术峰会,非常精彩,很受益。最近空闲下来,把嘉宾的PPT下载下来看了一通,当然有大牛的主题对我这个菜鸟来说还是看不懂。这里摘录了@高春辉 老师的《Bug Free 的 PHP 开发实践分享》的主题分享内容,我觉得很有价值很有实践指导意义,没有晦涩的技术流,但是很多都是PHP实践中值得注意的细节点。要想代码写的好,前提配置做的好error_reporting = E_ALL | E_STRICTdisplay_errors = 测试机设置为 On,生产机设置为 Offdisplay_startup_errors = Onlog_errors = Onerror_log = /home/logs/phperror.log写代码的时候要时刻注意的问题1、变量必须要初始化,函数或者类的方法的参数要有类型定义;2、能用 ===、!== 就不用 == 和 != ;3、对外来变量要做防卫式检查;4、不要只考虑正常逻辑,多考虑边界情况;5、涉及 SQL 以及文件操作要想象各种可能性,尽量在框架级别做好约束,不要依赖开发人员的能力;6、要让好的习惯成为你的本能!一些经验1、单入口;入口对一些容易出问题的事情进行检查和初始化,让程序员可以把精力集中在应用层。比如服务器时间出错检查,路径初始化,GET、POST、FILES 、SERVER 等全局变量的初始化,等等。2、用类封装代码;3、做好 Autoload,善用 NameSpace;4、接管异常处理,在代码里尽量抛异常;5、尽量使用原生和 PECL 扩展函数;6、代码里慎用 @ 符;7、为对 CDN 更友善,框架默认输出 no-cache 头,需要时再改变,并尽量把动态请求和静态资源分开;8、如果有文件上传功能,可以在入口处这样处理而不需要程序员来操心删掉临时文件:register_shutdown_function(‘removeFILESOnShutdown’);9、在允许的情况下,升级到更高 PHP 版本;10、通过 Xdebug 调试,使用 XHProf 了解性能问题并改进;11、APC、OpCache、Memcached 还用我说吗?但是在此之上最好再做一层封装,方便以后迁移和调试;12、多做 Code Review,三个月后再看自己的代码;13、框架和底层代码一定要经得起最严格的考验;14、一定要在最严格的方式下开发与测试,最好有独立的测试机;15、降低未来的维护成本,编码规范与代码规范,要严格执行,前者可以用 PHP_CodeSniffer 在提交到代码仓库时检查;16、服务分层,图像处理等耗时操作,不要和 web 服务混在一起。一个小技巧,一些无须用户关心的操作,比如记录用户信息,可以集中放到程序最后使用 fastcgi_finish_request() 方法在断开用户连接后执行。17、MySQL 数据库的运行状态可用 mysqltuner.pl 和 tuning-primer.sh 来检查;18、服务器以及服务的运行状态,要有及时的监控和报警,没精力,可以用监控宝。我们自己,走的更远1、框架会 unset 掉 GET、POST、COOKIE 等相关数据,对一些外来数据做初始化,比如 GET 操作下,FILES 变量会被清空,必须通过我们自己封装的方法进行外来数据的获取;2、我们针对前端 HTML 代码,分割静态资源并作自动优化,无须人工干预;3、文件储存实现了统一化,自动去重,这样对开发用户上传内容型的应用非常方便,而且一点都不用担心被上传注入;4、我们有专门的任务处理服务,通过 FastCGI 协议与前端进行通信,省掉 HTTP 层的开销;5、不仅 Web 是单一入口,任务处理、命令行和计划任务都做了单一入口。
2023年08月08日
9 阅读
0 评论
0 点赞
2023-08-08
对象关系行为模式之延迟加载
对象关系行为模式之延迟加载一、概念Lazy Load:一个对象,它虽然不包含所需要的所有数据,但是知道怎么获取这些数据。延迟加载貌似很简单,就是在数据需要时再从数据库获取,减少数据库的消耗。但这其中还是有不少技巧的。二、实现延迟加载实现Lazy Load主要有四种方法:延迟初始化、虚代理、值保持器和重影。(1)延迟初始化(Lazy initialization)1.1 概念这个是最简单的方法。意思就是每次访问属性域都要先检查该域是否为空,如果为空,再获取这个域的值。这样必须做到所有对该域的访问,即使来自类的内部,都要通过获取方法来实现。1.2 代码实现Php代码class Supplier{ private $products; public function getProducts(){ if($products == null) $products = $Product->findForSupplier(); return $products; } }1.3 使用时机只有在域需要另外的数据库访问时才考虑使用延迟加载。需要额外的调用,并且当使用主对象时所调用的数据没有用到的时候。最适用于活动记录、表数据入口和行数据入口。(2)虚代理(virtual proxy)2.1 概念实质为一对象,不包含任何东西,只有当它的一个方法被调用时,它才从数据库加载恰当的对象。说简单点说是一个对象的代理对象,初始化时不加载对象,只有当代理对象被调用方法时才真正去加载。2.2 代码实现Php代码/** * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 */ class VirtualProxy { private $holder = null; private $loader = null; /** * @param Closure $loader 生成被代理对象的闭包函数 */ public function __construct(Closure $loader) { $this->loader = $loader; } /** * 代理成员方法的调用 * * @param string $method * @param array $arguments * @throws BadMethodCallException * @return mixed */ public function __call($method, array $arguments = null) { $this->check(); if (!method_exists($this->holder, $method)) { throw new BadMethodCallException(); } return call_user_func_array( array(&$this->holder, $method), $arguments); } /** * 代理成员属性的读取 * * @param string $property * @throws ErrorException * @return mixed */ public function __get($property) { $this->check(); if (!isset($this->holder->$property)) { throw new ErrorException(); } return $this->holder->$property; } /** * 代理成员属性的赋值 * * @param string $property * @param mixed $value */ public function __set($property, $value) { $this->check(); $this->holder->$property = $value; } /** * 检查是否已经存在被代理对象,不存在则生成。 */ private function check() { if (null == $this->holder) { $loader = $this->loader; $this->holder = $loader(); } } } // 测试 $v = new VirtualProxy(function(){ echo 'Now, Loading', "\n"; $a = new ArrayObject(range(1,100)); $a->abc = 'a'; // 实际使用中,这里调用的是 DataMapper 的 findXXX 方法 // 返回的是领域对象集合 return $a; }); // 代理对象直接当作原对象访问 // 而此时构造方法传入的 callback 函数才被调用 // 从而实现加载对象操作的延迟 echo $v->abc . $v->offsetGet(50);(3)值保持器(value holder)3.1 概念一个用来包装某个其他对象的对象,要想获取基对象,可以访问值保持器得到它的值,但是只有第一次访问值保持器时它真正从数据库读取数据。(4)重影(ghost)4.1 概念部分状态下的真实对象,当从数据库加载对象的时候,它只包含其ID。当每次要访问某个域时,它就会加载其完全状态。把重影看成一个对象,它的每个域都是被一下子延迟初始化的,或者把它看成一个虚代理,对象本身就是它的虚代理。4.2 代码实现Php代码//继承要加载的对象 class DeferredEventCollection extends EventCollection { private $stmt; private $valueArray; private $run=false;//标识当前加载状态 //构造方法,不真正获取数据,只包含其$valueArray(ID) function __construct( Mapper $mapper, \PDOStatement $stmt_handle,array $valueArray ) { parent::__construct( null, $mapper ); $this->stmt = $stmt_handle; $this->valueArray = $valueArray; } //加载完全状态 function notifyAccess() { if ( ! $this->run ) { $this->stmt->execute( $this->valueArray ); $this->raw = $this->stmt->fetchAll(); $this->total = count( $this->raw ); } $this->run=true; } }三、延迟加载的风险1、继承常常会给延迟加载带来问题。如果要用重影,需要知道要创建什么类型的重影,如果没有正确加载数据,往往就很难说了。虚代理在静态数据类型语言中也会遇到同样的问题。2、延迟加载容易导致产生超出需要的数据库访问。书中别名“波动加载”。如用延迟加载来填充一个集合,然后每次只访问其中一个元素。这样就会每访问一个对象就访问一次数据库,而不是一次把所需对象全部读出来。这种加载方式会严重影响系统的性能。当然,可以不使用延迟加载的集合,而使类集合本身成为延迟加载,加载类集合时一次加载全部内容。四、小结延迟加载很适合于面向方面(AOP)的程序设计。可以将延迟加载操作置于一个单独的方面,这样能独立改变延迟加载策略,领域开发者也不必处理延迟加载的问题了。无论你是否在领域类中显式地添加延迟加载代码,延迟加载都是一个好习惯。除了类型安全之外,使用集合对象而非数组的好处是你可以使用延迟加载。
2023年08月08日
7 阅读
0 评论
0 点赞
2023-08-08
php中通过虚代理实现延迟加载的实现代码
php中通过虚代理实现延迟加载的实现代码基本原理是通过一个 虚代理(Virtual Proxy) 做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载(LazyLoad)。基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。不过我实现的这个版本有局限性:只适用于对象,无法代理数组等基本数据类型(需要用 ArrayObject 一类的内置对象封装)被代理之后,一些带有操作符重载性质的接口实现就失效了,例如 ArrayAccess 的索引器、Itreator 的迭代器,如果是用该代理来处理集合类型的延迟加载,还需要继承一个子类做特殊处理,以便外部用 foreach 迭代demo代码如下:// 测试 $v = new VirtualProxy(function(){ echo 'Now, Loading', "\n"; $a = new ArrayObject(range(1,100)); $a->abc = 'a'; // 实际使用中,这里调用的是 DataMapper 的 findXXX 方法 // 返回的是领域对象集合 return $a; }); // 代理对象直接当作原对象访问 // 而此时构造方法传入的 callback 函数才被调用 // 从而实现加载对象操作的延迟 echo $v->abc . $v->offsetGet(50);Virtual Proxy代码如下:/** * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * * @author tonyseek * */ class VirtualProxy { private $holder = null; private $loader = null; /** * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 * * @param Closure $loader 生成被代理对象的闭包函数 */ public function __construct(Closure $loader) { $this->loader = $loader; } /** * 代理成员方法的调用 * * @param string $method * @param array $arguments * @throws BadMethodCallException * @return mixed */ public function __call($method, array $arguments = null) { $this->check(); if (!method_exists($this->holder, $method)) { throw new BadMethodCallException(); } return call_user_func_array( array(&$this->holder, $method), $arguments); } /** * 代理成员属性的读取 * * @param string $property * @throws ErrorException * @return mixed */ public function __get($property) { $this->check(); if (!isset($this->holder->$property)) { throw new ErrorException(); } return $this->holder->$property; } /** * 代理成员属性的赋值 * * @param string $property * @param mixed $value */ public function __set($property, $value) { $this->check(); $this->holder->$property = $value; } /** * 检查是否已经存在被代理对象,不存在则生成。 */ private function check() { if (null == $this->holder) { $loader = $this->loader; $this->holder = $loader(); } }
2023年08月08日
12 阅读
0 评论
0 点赞
2023-08-08
用Zephir编写PHP扩展
用Zephir编写PHP扩展自从NodeJS,和Golang出来后,很多人都投奔过去了。不为什么,冲着那牛X的性能。那PHP的性能什么时候能提升一下呢?要不然就会被人鄙视了。其实大牛们也深刻体会到了这些威胁,于是都在秘密开发各种秘密武器。HHVM和HackFacebook自己弄了一套HHVM虚拟机,和一个新语言Hack。HHVM的性能不错,像Wordpress,PHPMyAdmin这样的项目,运行在上面很流畅,但是有个问题很致命,如果你引入了第三方扩展,现有的代码移植过去,没办法运行。如果你希望你的代码运行于HHVM,那么你需要编写基于HHVM的扩展,这时候你要学习C++了。很抓狂有木有?又或者,用Hack重写你的代码,这事谁会干呢?新项目可能可以拿来玩玩,但是旧的项目,如果代码量大,且代码混乱的项目,那就只能呵呵了。PHPNG(next generation)前些日子PHP核心开发组宣布了个利好消息,将在PHP 5.7版本会有很大的性能提升。这一次又打击到HHVM了。但是要等到5.7的版本才会发布。现在很多都只是停留在5.4的版本,鞭长莫及啊。除了这些,就没有办法提升性能了吗?有!------ PHP扩展。Phalcon没听过,Yaf总听过了吧。什么?都没听过?赶紧去Google下,听说面试会加分。PHP扩展PHP的流行,得益于它的扩展系统。开发者通过为PHP开发扩展,通过这个中间件,跟其他系统连接通信。例如我们常用的cURL,Memcache和Redis等扩展。这些扩展不包含在PHP核心,需要额外编译。这里有一份官方列出的PHP扩展列表:http://www.php.net/manual/en/extensions.alphabetical.php如果你想自己编写PHP扩展,意味着你需要掌握C语言,因为PHP的扩展是通过C编写的,而且你还需要掌握PHP的Zend API,了解它的核心原理。如果你有兴趣,可以参考:《深入理解PHP内核》。如果你懂C,那么你看完上面这本书,那么你大概也能写了。但是,对于C语言水平比较菜,或者不怎么懂C的人来说,就只能望而却步了。为什么我要写PHP扩展呢?访问现有的库。假设现在有一个库很好用(例如MongoDB),你希望在PHP也能用上它。如果这个库很热门,那么你就走运了,应该有大牛帮你实现了。要是运气不好,这个库比较冷门,但你业务需求又刚好需要用到的话,那只能干着急了(当然这种情况是极少出现的)。性能。PHP是动态语言,代码性能比C语言相差一个级别。正是由于此原因,产生了Yaf,Phalcon这样的PHP的扩展框架。对于那些不想学C,但又想要得到编写自己的扩展,怎么办?Zephir分析了以上的种种不靠谱,终于进入了正题。现在隆重向你介绍一个叫Zephir的项目。它可以帮助你使用类PHP的语法,来生成C语言代码,并帮助你编译成PHP扩展。是不是很酷?很酷,有没有?Show Me The Code如果你用C写一个Hello World的扩展,那么你需要这样写:ifdef HAVE_CONFIG_Hinclude "config.h"endifinclude "php.h"include "php_test.h"include "test.h"include "kernel/main.h"/**This is a sample class */ZEPHIR_INIT_CLASS(Test_Hello) {ZEPHIR_REGISTER_CLASS(Test, Hello, hello, test_hello_method_entry, 0); return SUCCESS;}/**This is a sample method */PHP_METHOD(Test_Hello, say) {php_printf("%s", "Hello World!");}而Zephir则只需要这样:01.namespace Test;02.03./**04.* This is a sample class05.*/06.class Hello07.{08./**09.* This is a sample method10.*/11.public function say()12.{13.echo "Hello World!";14.}15.}是不是跟写PHP代码没什么区别?安装 Zephir1.$ git clone https://github.com/json-c/json-c.git2.$ cd json-c3.$ sh autogen.sh4.$ ./configure5.$ make && sudo make install1.$ git clone https://github.com/phalcon/zephir2.$ cd zephir3.$ ./install -c安装完成后,运行1.$ zephir help如果没有报错,说明你已经安装成功了。Zephir语法Zephir跟PHP有几点区别:Zephir是强类型语言。变量有自己的类型。01.namespace Test;02.03.class Arithmetic04.{05.public function intSum()06.{07.int a, b, c;08.09.let a = 1,10.b = 2,11.c = a + b;12.13.return c;14.}15.}这里需要特别注意的是Zephir有个let关键字,用于变量赋值。编译扩展初始化一个Zephir扩展1.zephir init myframework新建一个叫 calculator.zep的文件1.namespace Myframework;2.class Calculator {3.public function add(int a, int b) {4.return a + b;5.}6.}Zephir必须指定一个命名空间,上面的例子Myframework为这次Demo的命名空间。Zephir遵循PSR-1的标准进行命名。把Zephir代码编译成PHP的C扩展1.zephir build开启扩展在你的php.ini文件加上1.extension=myframework.so测试1.$ php -a2.php > $calc = new Myframework\Calculator;3.php > var_dump($calc->add(2, 1));4.int(3)是不是很简单?你也来尝试一下吧。用Zephir开发PHP扩展
2023年08月08日
24 阅读
0 评论
0 点赞
2023-08-08
php return 和 finally 组合使用,使return不终止函数运行
php return 和 finally 组合使用,使return不终止函数运行如下示例:php>=5.5<?php function example() { try { //例如打开mysql连接 if(condition) { return false; } } finally { // 关闭sql连接,这里会执行即使return被调用。 } } ?>
2023年08月08日
11 阅读
0 评论
0 点赞
1
...
84
85
86
...
112