首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
136 阅读
2
php接口优化 使用curl_multi_init批量请求
130 阅读
3
2024年备考系统架构设计师
102 阅读
4
《从菜鸟到大师之路 ElasticSearch 篇》
101 阅读
5
PHP 文件I/O
89 阅读
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
累计撰写
785
篇文章
累计收到
7
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
785
篇与
的结果
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日
13 阅读
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 点赞
2023-08-08
PHP捕获Fatal error错误的方法
PHP捕获Fatal error错误的方法这篇文章主要介绍了PHP捕获Fatal error错误的方法,使用register_shutdown_function来捕获Fatal error错误,需要的朋友可以参考下Fatal error 一般是不需要捕获的, 但是在一个复杂的程序中, 如果偶然出现内存不足导致fatal error就难以处理了.比如. fatal error 出在MySQL类中fetch的时候. 这个时候就很难定位到真正问题所在了.PHP异常处理中 可以通过set_error_handler来捕获. 但是却只能捕获 NOTICE/WARNING级别的错误, 对于E_ERROR是无能为力的.register_shutdown_function 能解决set_error_handler的不足.通过此函数注册好程序结束回调函数, 就可以捕获平时捕获不到的错误了. 再通过 error_get_last 对错误进行判断. 就容易找出难以定位的问题了.function shutdown_function() { $e = error_get_last(); print_r($e); } register_shutdown_function('shutdown_function');
2023年08月08日
7 阅读
0 评论
0 点赞
2023-08-08
php错误及异常捕捉
php错误及异常捕捉在实际开发中,错误及异常捕捉仅仅靠try{}catch()是远远不够的。所以引用以下几中函数。a) set_error_handler一般用于捕捉 E_NOTICE 、E_USER_ERROR、E_USER_WARNING、E_USER_NOTICE不能捕捉:E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR and E_COMPILE_WARNING。一般与trigger_error("...", E_USER_ERROR),配合使用。<?php// we will do our own error handlingerror_reporting(0);function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars){// timestamp for the error entry $dt = date("Y-m-d H:i:s (T)"); // define an assoc array of error string // in reality the only entries we should // consider are E_WARNING, E_NOTICE, E_USER_ERROR, // E_USER_WARNING and E_USER_NOTICE $errortype = array ( E_ERROR => 'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error' ); // set of errors for which a var trace will be saved $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); $err = "<errorentry>\n"; $err .= "\t<datetime>" . $dt . "</datetime>\n"; $err .= "\t<errornum>" . $errno . "</errornum>\n"; $err .= "\t<errortype>" . $errortype[$errno] . "</errortype>\n"; $err .= "\t<errormsg>" . $errmsg . "</errormsg>\n"; $err .= "\t<scriptname>" . $filename . "</scriptname>\n"; $err .= "\t<scriptlinenum>" . $linenum . "</scriptlinenum>\n"; if (in_array($errno, $user_errors)) { $err .= "\t<vartrace>" . wddx_serialize_value($vars, "Variables") . "</vartrace>\n"; } $err .= "</errorentry>\n\n"; echo $err;}function distance($vect1, $vect2) {if (!is_array($vect1) || !is_array($vect2)) { trigger_error("Incorrect parameters, arrays expected", E_USER_ERROR); return NULL; } if (count($vect1) != count($vect2)) { trigger_error("Vectors need to be of the same size", E_USER_ERROR); return NULL; } for ($i=0; $i<count($vect1); $i++) { $c1 = $vect1[$i]; $c2 = $vect2[$i]; $d = 0.0; if (!is_numeric($c1)) { trigger_error("Coordinate $i in vector 1 is not a number, using zero",E_USER_WARNING); $c1 = 0.0; } if (!is_numeric($c2)) { trigger_error("Coordinate $i in vector 2 is not a number, using zero",E_USER_WARNING); $c2 = 0.0; } $d += $c2*$c2 - $c1*$c1; } return sqrt($d);}$old_error_handle = set_error_handler("userErrorHandler");$t = I_AM_NOT_DEFINED; //generates a warning// define some "vectors"$a = array(2, 3, "foo");$b = array(5.5, 4.3, -1.6);$c = array(1, -3);//generate a user error$t1 = distance($c,$b);// generate another user error$t2 = distance($b, "i am not an array") . "\n";// generate a warning$t3 = distance($a, $b) . "\n";?>b) set_exception_handler设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。与throw new Exception('Uncaught Exception occurred'),连用。<?php// we will do our own error handlingerror_reporting(0);function exceptHandle($errno, $errmsg, $filename, $linenum, $vars){// timestamp for the error entry $dt = date("Y-m-d H:i:s (T)"); // define an assoc array of error string // in reality the only entries we should // consider are E_WARNING, E_NOTICE, E_USER_ERROR, // E_USER_WARNING and E_USER_NOTICE $errortype = array ( E_ERROR => 'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error' ); // set of errors for which a var trace will be saved $err = "<errorentry>\n"; $err .= "\t<datetime>" . $dt . "</datetime>\n"; $err .= "\t<errornum>" . $errno . "</errornum>\n"; $err .= "\t<errortype>" . $errortype[$errno] . "</errortype>\n"; $err .= "\t<errormsg>" . $errmsg . "</errormsg>\n"; $err .= "\t<scriptname>" . $filename . "</scriptname>\n"; $err .= "\t<scriptlinenum>" . $linenum . "</scriptlinenum>\n"; if (1) { $err .= "\t<vartrace>" . wddx_serialize_value($vars, "Variables") . "</vartrace>\n"; } $err .= "</errorentry>\n\n"; echo $err;}$old_except_handle = set_exception_handler("exceptHandle");//$t = I_AM_NOT_DEFINED; //generates a warning$a;throw new Exception('Uncaught Exception occurred'); ?>c) register_shutdown_function执行机制是:php把要调用的函数调入内存。当页面所有PHP语句都执行完成时,再调用此函数。一般与trigger_error("...", E_USER_ERROR),配合使用。<?phperror_reporting(0);date_default_timezone_set('Asia/Shanghai');register_shutdown_function('my_exception_handler');$t = I_AM_NOT_DEFINED; //generates a warningtrigger_error("Vectors need to be of the same size", E_USER_ERROR); function my_exception_handler(){if($e = error_get_last()) { //$e['type']对应php_error常量 $message = ''; $message .= "出错信息:\t".$e['message']."\n\n"; $message .= "出错文件:\t".$e['file']."\n\n"; $message .= "出错行数:\t".$e['line']."\n\n"; $message .= "\t\t请工程师检查出现程序".$e['file']."出现错误的原因\n"; $message .= "\t\t希望能您早点解决故障出现的原因<br/>"; echo $message; //sendemail to }}?>c) restore_error_handler()函数定义和用法 restore_error_handler() 函数恢复之前的错误处理程序,该程序是由 set_error_handler() 函数改变的。该函数永远返回 true。是 set_error_handler()的反函数。
2023年08月08日
10 阅读
0 评论
0 点赞
1
...
119
120
121
...
157