首页
关于
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
非常实用的15款开源PHP类库
非常实用的15款开源PHP类库PHP库给开发者提供了一个标准接口,它帮助开发者在PHP里充分利用面向对象编程。这些库为特定类型的内置功能提供了一个标准的API,允许类可以与PHP引擎进行无缝的交互。此外,开发者使用这些类库还可以简化工作流程,提供工作效率。下面就一起来看看这些非常实用且免费的类库吧,希望它们能助你一臂之力。1.RequestsRequests是一个用PHP编写的HTTP库,遵循ISC开源协议,托管在GitHub上。Requests取代了Python HTTP/1.1以外的一切工作———让你与Web服务可以无缝的结合。Requests提供了一致的API,并且使用cURL或fsockopen(具体取决于可用性),它还简化了发送请求,接受HEAD、GET、POST、PUT、DELETE或PATCH并且添加标头、表单数据和多个部分组成的文件。其次,该库还适用于国际域名、身份验证、自动压缩gzip压缩响应等。综上所述可以看出,Requests是一个非常好用且可以友好托管HTTP请求的标签。2.MuneeMunee是一个集图片尺寸调整、CSS-JS合并/压缩、缓存等功能于一身的PHP库。可以在服务器端和客户端缓存资源。它集成了PHP图片操作库Imagine来实现图片尺寸调整和剪切,之后进行缓存。Munee可以自动编译LESS、SCSS和CoffeeScript,并且可以把CSS+JS文件合并成一个单一的请求,此外,还可以对这些CSS-JS文件进行精缩,让其拥有更好的性能表现。该库还可以轻易地与任何代码集成。3.RatchetRatchet是一个PHP库、WebSockets工具包,开发者可以使用它在客户端和服务器端之间构建实时、双向的App应用,并且可以快速简单地构建事件驱动应用程序(而不是传统的HTTP 请求/响应应用程序)。4.Swift MailerSwift Mailer是一个功能丰富的PHP邮件库,不依赖于PHP自带的mail() 函数,因为该函数在发送多个邮件时占用的系统资源很高。Swift直接与SMTP服务器通讯,具有非常高的发送速度和效率。5.UnirestUnirest是一个轻量级的HTTP开发库,可用于PHP、Ruby、Python、Java、Objective-C等开发语言。支持GET、POST、PUT、UPDATE、DELETE操作,它的调用方法与返回结果对所有开发语言来说,都是相同的。6.DetectorDetector是一个开源的PHP类库,用于检测用户的浏览器环境。它可以获得浏览器的使用情况和浏览器的HTML5 CSS3功能、并分析是否是移动、平板电脑、桌面或网页爬虫和其他项,如:颜色深度、 视频尺寸、Cookie等。该库对每个浏览器用户都使用单一的用户代理字符串来自动适应新浏览器、版本和设备。7.PHP ThumbPHP Thumb是一个PHP类,用来生成图片的缩略图。 只需数行代码即可,支持多种图片来源,包括文件系统或者数据库,支持大多数图片格式。并可对图片进行旋转、剪切、加水印等等。可自定义缩略图的质量,提供内建的缓存以降低服务器的负载。8.Zebra ImageZebra Image是一个开源的轻量级图像处理库,并且是一款面向对象库,只需PHP GD2扩展,并支持缩放、裁剪、旋转和翻转操作。它可以用于.jpg、.gif、.png等格式。9.Hybrid AuthHybridAuth是一个开源PHP类库,用于通过微博/社交网站和ID来提供验证功能实现同步登录网站功能。它能够很方便的与现有网站相集成,只要引用一个文件并添加几行代码就能够实现登录。一旦验证,HybridAuth会提供连接用户的标准化相关资料。此外,除了验证功能,这个类库能够让我们与用户连接的social API客户端相交互。10. Gantt ChartsGantti是一个开源的PHP类,帮助用户即时生成Gantt图表。使用Gantti创建图表无需使用JavaScript,是纯HTML5-CSS3。图表默认输出非常漂亮,但用户可以自定义样式进行输出(SASS样式表)。11.Mobile DetectMobile Detect是一个PHP类,通过User-Agent检测各种手机设备,并结合HTTP Header来检测移动设备环境。该类库最强大的地方是,它有一个非常完整的库,可以检测出所用的设备类型(包括操作类型、以及手机品牌等都能检测)和浏览器的详细信息。12.ImageWorkshop顾名思义,ImageWorkshop是一个管理和操作图片的PHP类库,这个类拥有类似图片编辑软件的逻辑:基于层的概念,可以叠加很多层或层组(每一层不同的操纵选项)。它还支持许多功能,比如水印、裁剪、移动、缩放、旋转、叠加等。13.JqmPhpJqmPhp是一个PHP开源类库,旨在简化jQuery与PHP来进行移动开发,用于生成使用jQuery Mobile框架所需要的HTML文件。该类库的文件是独立的,所以你可以根据需要来选择使用。14.PHP Image CacheImage Cache是一个轻量级的PHP类,可以在用户浏览器里压缩、移动、缓存图片。这个类提供一些简单的设置如:目录、根路径URL等,然后针对每一张图片调用压缩功能。15.ImagineImagine是一个面向对象的PHP类库,用于图片操作。这个类库能够处理一些经常用到的操作如:缩放、裁剪、应用过滤等。其Color类库可用于对任意特定的颜色生成RGB值。并且还提供一些方法来绘制图形如:圆弧、椭圆、线、片等。
2023年08月08日
12 阅读
0 评论
0 点赞
2023-08-08
php中的数种依赖注入
php中的数种依赖注入经常看到却一直不甚理解的概念,依赖注入(DI)以及控制器反转(Ioc),找了几篇好的文章,分享一下。 自己理解的,依赖注入就是组件通过构造器,方法或者属性字段来获取相应的依赖对象。举个现实生活中的例子来理解, 比如我要一把菜刀 如何获得1.可以自己造一把,对应new一个。2.可以找生产菜刀的工厂去买一把,对应工厂模式。3.可以打电话 让店家送货上门,对应依赖注入。再比如我是一个演员,我不可能要求某个导演,我要演某某剧的男一号,相反,导演可以决定让谁来演。而我们的object就是这个演员。注入的几个途径:1.construct注入帮助<?phpclass Book { private $db_conn; public function __construct($db_conn) { $this->db_conn = $db_conn;}}但是如果依赖过多,那么在构造方法里必然传入多个参数,三个以上就会使代码变的难以阅读。2.set注入帮助<?php $book = new Book(); $book->setdb($db); $book->setprice($price); $book->set_author($author);?>代码很清晰,但是当我们需要注入第四个依赖时,意味着又要增加一行。比较好的解决办法是 建立一个class作为所有依赖关系的container,在这个class中可以存放、创建、获取、查找需要的依赖关系帮助<?phpclass Ioc { protected $db_conn; public static function make_book() { $new_book = new Book(); $new_book->set_db(self::$db_conn); //... //... //其他的依赖注入 return $new_book;}}此时,如果获取一个book实例,只需要执行$newone = Ioc::makebook();以上是container的一个具体实例,最好还是不要把具体的某个依赖注入写成方法,采用registry注册,get获取比较好。帮助<?phpclass Ioc {/**@var 注册的依赖数组*/ protected static $registry = array(); /**添加一个resolve到registry数组中@param string $name 依赖标识@param object $resolve 一个匿名函数用来创建实例@return void */public static function register($name, Closure $resolve) {static::$registry[$name] = $resolve;} /**返回一个实例@param string $name 依赖的标识@return mixed */public static function resolve($name) { if ( static::registered($name) ) { $name = static::$registry[$name]; return $name(); } throw new Exception('Nothing registered with that name, fool.');} /**查询某个依赖实例是否存在@param string $name id@return bool */public static function registered($name) {return array_key_exists($name, static::$registry);}}现在就可以通过如下方式来注册和注入一个依赖帮助<?php$book = Ioc::registry('book', function(){$book = new Book;$book->setdb('...');$book->setprice('...');return $book;});//注入依赖$book = Ioc::resolve('book');?>http://net.tutsplus.com/tutorials/php/dependency-injection-huhhttp://scriptogr.am/mattsah/post/dependencies-in-phphttp://martinfowler.com/articles/injection.htmlhttp://www.potstuck.com/2009/01/08/php-dependency-injection/http://www.potstuck.com/2010/09/09/php-dependency-a-php-dependency-injection-framework/http://www.cnblogs.com/Seekr/archive/2012/06/20/2556463.html
2023年08月08日
10 阅读
0 评论
0 点赞
2023-08-08
PHP非阻塞模式
PHP非阻塞模式让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施:一、若你使用的是FastCGI模式,使用fastcgi_finish_request()能马上结束会话,但PHP线程继续在跑。帮助echo "program start.";file_put_contents('log.txt','start-time:'.date('Y-m-d H:i:s'), FILE_APPEND);fastcgi_finish_request();sleep(1);echo 'debug...';file_put_contents('log.txt', 'start-proceed:'.date('Y-m-d H:i:s'), FILE_APPEND);sleep(10);file_put_contents('log.txt', 'end-time:'.date('Y-m-d H:i:s'), FILE_APPEND);这个例子输出结果可看到输出program start.后会话就返回了,所以debug那个输出浏览器是接收不到的,而log.txt文件能完整接收到三个完成时间。二、使用fsockopen、cUrl的非阻塞模式请求另外的网址帮助$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);if (!$fp) die('error fsockopen');stream_set_blocking($fp,0);$http = "GET /save.php / HTTP/1.1\r\n"; $http .= "Host: www.example.com\r\n"; $http .= "Connection: Close\r\n\r\n";fwrite($fp,$http);fclose($fp);利用cURL中的curl_multi_*函数发送异步请求帮助$cmh = curl_multi_init();$ch1 = curl_init();curl_setopt($ch1, CURLOPT_URL, "http://localhost:6666/child.php");curl_multi_add_handle($cmh, $ch1);curl_multi_exec($cmh, $active);echo "End\n";三、使用Gearman、Swoole扩展Gearman是一个具有php扩展的分布式异步处理框架,能处理大批量异步任务;Swoole最近很火,有很多异步方法,使用简单。(尘缘注:号称重新定义PHP,把NodeJS喷得体无完肤。Swoole工具虽好,却感觉是扩展本身跟NodeJS没可比性)四、使用redis等缓存、队列,将数据写入缓存,使用后台计划任务实现数据异步处理。这个方法在常见的大流量架构中应该很常见吧五、极端的情况下,可以调用系统命令,可以将数据传给后台任务执行,个人感觉不是很高效。帮助12$cmd = 'nohup php ./processd.php $someVar >/dev/null &';$cmd六、外国佬的大招,没看懂,php原生支持http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html七、安装pcntl扩展,使用pcntl_fork生成子进程异步执行任务,个人觉得是最方便的,但也容易出现zombie process。帮助if (($pid = pcntl_fork()) == 0) {child_func(); //子进程函数,主进程运行} else {father_func(); //主进程函数}echo "Process " . getmypid() . " get to the end.\n";function father_func() {echo "Father pid is " . getmypid() . "\n";}function child_func() {sleep(6); echo "Child process exit pid is " . getmypid() . "\n"; exit(0);}
2023年08月08日
8 阅读
0 评论
0 点赞
2023-08-08
TCP的三次握手与四次挥手理解
TCP的三次握手与四次挥手理解
2023年08月08日
12 阅读
0 评论
0 点赞
2023-08-08
理解PHP 依赖注入|Laravel IoC容器
理解PHP 依赖注入|Laravel IoC容器看Laravel的IoC容器文档只是介绍实例,但是没有说原理,之前用MVC框架都没有在意这个概念,无意中在phalcon的文档中看到这个详细的介绍,感觉豁然开朗,复制粘贴过来,主要是好久没有写东西了,现在确实很懒变得!首先,我们假设,我们要开发一个组件命名为SomeComponent。这个组件中现在将要注入一个数据库连接。在这个例子中,数据库连接在component中被创建,这种方法是不切实际的,这样做的话,我们将不能改变数据库连接参数及数据库类型等一些参数。01 <?php02 03 class SomeComponent04 {05 06 /**07 * The instantiation of the connection is hardcoded inside08 * the component so is difficult to replace it externally09 * or change its behavior10 */11 public function someDbTask()12 {13 $connection = new Connection(array(14 "host" => "localhost",15 "username" => "root",16 "password" => "secret",17 "dbname" => "invo"18 ));19 20 // ...21 }22 23 }24 25 $some = new SomeComponent();26 $some->someDbTask();为了解决上面所说的问题,我们需要在使用前创建一个外部连接,并注入到容器中。就目前而言,这看起来是一个很好的解决方案:01 <?php02 03 class SomeComponent04 {05 06 protected $_connection;07 08 /**09 * Sets the connection externally10 */11 public function setConnection($connection)12 {13 $this->_connection = $connection;14 }15 16 public function someDbTask()17 {18 $connection = $this->_connection;19 20 // ...21 }22 23 }24 25 $some = new SomeComponent();26 27 //Create the connection28 $connection = new Connection(array(29 "host" => "localhost",30 "username" => "root",31 "password" => "secret",32 "dbname" => "invo"33 ));34 35 //Inject the connection in the component36 $some->setConnection($connection);37 38 $some->someDbTask();现在我们来考虑一个问题,我们在应用程序中的不同地方使用此组件,将多次创建数据库连接。使用一种类似全局注册表的方式,从这获得一个数据库连接实例,而不是使用一次就创建一次。01 <?php02 03 class Registry04 {05 06 /**07 * Returns the connection08 */09 public static function getConnection()10 {11 return new Connection(array(12 "host" => "localhost",13 "username" => "root",14 "password" => "secret",15 "dbname" => "invo"16 ));17 }18 19 }20 21 class SomeComponent22 {23 24 protected $_connection;25 26 /**27 * Sets the connection externally28 */29 public function setConnection($connection){30 $this->_connection = $connection;31 }32 33 public function someDbTask()34 {35 $connection = $this->_connection;36 37 // ...38 }39 40 }41 42 $some = new SomeComponent();43 44 //Pass the connection defined in the registry45 $some->setConnection(Registry::getConnection());46 47 $some->someDbTask();现在,让我们来想像一下,我们必须在组件中实现两个方法,首先需要创建一个新的数据库连接,第二个总是获得一个共享连接:01 <?php02 03 class Registry04 {05 06 protected static $_connection;07 08 /**09 * Creates a connection10 */11 protected static function _createConnection()12 {13 return new Connection(array(14 "host" => "localhost",15 "username" => "root",16 "password" => "secret",17 "dbname" => "invo"18 ));19 }20 21 /**22 * Creates a connection only once and returns it23 */24 public static function getSharedConnection()25 {26 if (self::$_connection===null){27 $connection = self::_createConnection();28 self::$_connection = $connection;29 }30 return self::$_connection;31 }32 33 /**34 * Always returns a new connection35 */36 public static function getNewConnection()37 {38 return self::_createConnection();39 }40 41 }42 43 class SomeComponent44 {45 46 protected $_connection;47 48 /**49 * Sets the connection externally50 */51 public function setConnection($connection){52 $this->_connection = $connection;53 }54 55 /**56 * This method always needs the shared connection57 */58 public function someDbTask()59 {60 $connection = $this->_connection;61 62 // ...63 }64 65 /**66 * This method always needs a new connection67 */68 public function someOtherDbTask($connection)69 {70 71 }72 73 }74 75 $some = new SomeComponent();76 77 //This injects the shared connection78 $some->setConnection(Registry::getSharedConnection());79 80 $some->someDbTask();81 82 //Here, we always pass a new connection as parameter83 $some->someOtherDbTask(Registry::getConnection());到此为止,我们已经看到了如何使用依赖注入解决我们的问题。不是在代码内部创建依赖关系,而是让其作为一个参数传递,这使得我们的程序更容易维护,降低程序代码的耦合度,实现一种松耦合。但是从长远来看,这种形式的依赖注入也有一些缺点。例如,如果组件中有较多的依赖关系,我们需要创建多个setter方法传递,或创建构造函数进行传递。另外,每次使用组件时,都需要创建依赖组件,使代码维护不太易,我们编写的代码可能像这样:01 <?php02 03 //Create the dependencies or retrieve them from the registry04 $connection = new Connection();05 $session = new Session();06 $fileSystem = new FileSystem();07 $filter = new Filter();08 $selector = new Selector();09 10 //Pass them as constructor parameters11 $some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector);12 13 // ... or using setters14 15 $some->setConnection($connection);16 $some->setSession($session);17 $some->setFileSystem($fileSystem);18 $some->setFilter($filter);19 $some->setSelector($selector);我想,我们不得不在应用程序的许多地方创建这个对象。如果你不需要依赖的组件后,我们又要去代码注入部分移除构造函数中的参数或者是setter方法。为了解决这个问题,我们再次返回去使用一个全局注册表来创建组件。但是,在创建对象之前,它增加了一个新的抽象层:01 <?php02 03 class SomeComponent04 {05 06 // ...07 08 /**09 * Define a factory method to create SomeComponent instances injecting its dependencies10 */11 public static function factory()12 {13 14 $connection = new Connection();15 $session = new Session();16 $fileSystem = new FileSystem();17 $filter = new Filter();18 $selector = new Selector();19 20 return new self($connection, $session, $fileSystem, $filter, $selector);21 }22 23 }这一刻,我们好像回到了问题的开始,我们正在创建组件内部的依赖,我们每次都在修改以及找寻一种解决问题的办法,但这都不是很好的做法。一种实用和优雅的来解决这些问题,是使用容器的依赖注入,像我们在前面看到的,容器作为全局注册表,使用容器的依赖注入做为一种桥梁来解决依赖可以使我们的代码耦合度更低,很好的降低了组件的复杂性:01 <?php02 03 class SomeComponent04 {05 06 protected $_di;07 08 public function __construct($di)09 {10 $this->_di = $di;11 }12 13 public function someDbTask()14 {15 16 // Get the connection service17 // Always returns a new connection18 $connection = $this->_di->get('db');19 20 }21 22 public function someOtherDbTask()23 {24 25 // Get a shared connection service,26 // this will return the same connection everytime27 $connection = $this->_di->getShared('db');28 29 //This method also requires a input filtering service30 $filter = $this->_db->get('filter');31 32 }33 34 }35 36 $di = new PhalconDI();37 38 //Register a "db" service in the container39 $di->set('db', function(){40 return new Connection(array(41 "host" => "localhost",42 "username" => "root",43 "password" => "secret",44 "dbname" => "invo"45 ));46 });47 48 //Register a "filter" service in the container49 $di->set('filter', function(){50 return new Filter();51 });52 53 //Register a "session" service in the container54 $di->set('session', function(){55 return new Session();56 });57 58 //Pass the service container as unique parameter59 $some = new SomeComponent($di);60 61 $some->someTask();现在,该组件只有访问某种service的时候才需要它,如果它不需要,它甚至不初始化,以节约资源。该组件是高度解耦。他们的行为,或者说他们的任何其他方面都不会影响到组件本身。我们的实现办法¶PhalconDI 是一个实现了服务的依赖注入功能的组件,它本身也是一个容器。由于Phalcon高度解耦,PhalconDI 是框架用来集成其他组件的必不可少的部分,开发人员也可以使用这个组件依赖注入和管理应用程序中不同类文件的实例。基本上,这个组件实现了 Inversion of Control 模式。基于此,对象不再以构造函数接收参数或者使用setter的方式来实现注入,而是直接请求服务的依赖注入。这就大大降低了整体程序的复杂性,因为只有一个方法用以获得所需要的一个组件的依赖关系。此外,这种模式增强了代码的可测试性,从而使它不容易出错。在容器中注册服务¶框架本身或开发人员都可以注册服务。当一个组件A要求调用组件B(或它的类的一个实例),可以从容器中请求调用组件B,而不是创建组件B的一个实例。这种工作方式为我们提供了许多优点:我们可以更换一个组件,从他们本身或者第三方轻松创建。在组件发布之前,我们可以充分的控制对象的初始化,并对对象进行各种设置。我们可以使用统一的方式从组件得到一个结构化的全局实例服务可以通过以下几种方式注入到容器:01 <?php02 03 //Create the Dependency Injector Container04 $di = new PhalconDI();05 06 //By its class name07 $di->set("request", 'PhalconHttpRequest');08 09 //Using an anonymous function, the instance will lazy loaded10 $di->set("request", function(){11 return new PhalconHttpRequest();12 });13 14 //Registering directly an instance15 $di->set("request", new PhalconHttpRequest());16 17 //Using an array definition18 $di->set("request", array(19 "className" => 'PhalconHttpRequest'20 ));在上面的例子中,当向框架请求访问一个请求数据时,它将首先确定容器中是否存在这个”reqeust”名称的服务。容器会反回一个请求数据的实例,开发人员最终得到他们想要的组件。在上面示例中的每一种方法都有优缺点,具体使用哪一种,由开发过程中的特定场景来决定的。用一个字符串来设定一个服务非常简单,但缺少灵活性。设置服务时,使用数组则提供了更多的灵活性,而且可以使用较复杂的代码。lambda函数是两者之间一个很好的平衡,但也可能导致更多的维护管理成本。PhalconDI 提供服务的延迟加载。除非开发人员在注入服务的时候直接实例化一个对象,然后存存储到容器中。在容器中,通过数组,字符串等方式存储的服务都将被延迟加载,即只有在请求对象的时候才被初始化。01 <?php02 03 //Register a service "db" with a class name and its parameters04 $di->set("db", array(05 "className" => "PhalconDbAdapterPdoMysql",06 "parameters" => array(07 "parameter" => array(08 "host" => "localhost",09 "username" => "root",10 "password" => "secret",11 "dbname" => "blog"12 )13 )14 ));15 16 //Using an anonymous function17 $di->set("db", function(){18 return new PhalconDbAdapterPdoMysql(array(19 "host" => "localhost",20 "username" => "root",21 "password" => "secret",22 "dbname" => "blog"23 ));24 });以上这两种服务的注册方式产生相同的结果。然后,通过数组定义的,在后面需要的时候,你可以修改服务参数:1 <?php2 3 $di->setParameter("db", 0, array(4 "host" => "localhost",5 "username" => "root",6 "password" => "secret"7 ));从容器中获得服务的最简单方式就是使用”get”方法,它将从容器中返回一个新的实例:1 <?php $request = $di->get("request");或者通过下面这种魔术方法的形式调用:1 <?php2 3 $request = $di->getRequest();4 5 PhalconDI 同时允许服务重用,为了得到一个已经实例化过的服务,可以使用 getShared() 方法的形式来获得服务。具体的 PhalconHttpRequest 请求示例:1 <?php2 3 $request = $di->getShared("request");参数还可以在请求的时候通过将一个数组参数传递给构造函数的方式:1 <?php2 3 $component = $di->get("MyComponent", array("some-parameter", "other"))
2023年08月08日
11 阅读
0 评论
0 点赞
1
...
121
122
123
...
157