脚本宝典收集整理的这篇文章主要介绍了

php框架

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

php框架的功能通用的路由,autoload。服务端mysql封装,日志组件。前端的页面渲染(smarty封装个)。在工作时听说别的部门换框架性能提升,所以调研了下常见的框架,包含ci,laravel,yii,yaf,会介绍下功能,另外给出号称最快框架yaf和常用yii和裸写框架的性能差。另外想实现rpc并发,http一般用过multi_curl可以,公司用的thrift没有实现并发,所以研究了下php协程,curl_multi,swoole异步,rpc中并发实现,corotine等。

常用php框架提供功能

  • ci http://codeigniter.org.cn/use...
    Route.
    autoload.载入文件正常controller 中load->helper(xx)。直接用xx
    log. db. hook.公共函数。
    代码逻辑分层。
    ui抽象。模板。
  • laravel https://laravel-china.org/doc...
    路由
    中间件(前置后置)
    配置区分环境,本地和线上密码不放其中
    数据库 创建表,编辑,删除,迁移,回滚,软删除和恢复(标记删除位)。ORM链式操作
    依赖注入,依赖自动发现。

    IOC 平时的if new 这种工厂模式,IoC模式看作工厂模式的升华,以前在工厂模式里写死了的对象,IoC模式    改为配置XML文件,这就把工厂和要生成的对象两者隔离 类(DatabaseQueue,queue,QueueContract),serviceprovider(外部调这个)=>bind(将类绑定到容器)。调用Queue::xx。依赖注入可以直接调用$类->method。通过门面可以类::method 【https://www.cnblogs.com/shiwenhu/p/6882340.html】

    事件

    事件映射protected $listen = [     'AppEventsOrderShipped' => [         'AppListenersSendShipmentNotification',     ],]; 写事件OrderShipped,写监听SendShipmentNotification 可以继承队列 分发事件:public function ship($orderId)     {     order=Order::findOrFail(orderId);     // 订单的发货逻辑...     event(new OrderShipped($order));     }

    队列 ,redis,db, 广播
    js监听
    任务调度 只是cron

  • yii https://www.yiichina.com/doc/...
    功能全面读介于ci和laravel之间,前端支持功能丰富。组件和行为是它的特色
    行为

    要定义行为,通过继承 yiibaseBehavior 。覆盖其中的events方法, public function events() {      return [          ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',          ];  }  public function beforeValidate($event) {      // 处理器方法逻辑  }, 附加行为:lass User extends ActiveRecord {  public function behaviors() {      return [         [          'class' => MyBehavior::className(),          'prop1' => 'value1',          'prop2' => 'value2',      ]]}}或者attach组件就可以使用行为了。

    直观感受下
    clipboard.png

  • yaf http://www.laruence.com/manua...
    php的一个扩展,因为是扩展,所以可以常驻内存,不用每次加载框架了、实现了基本功能
    路由,
    插件可以在几个hook处调用,比如自己开发一个Log,在这些Hook的地方加入回调(https://github.com/akDevelope...
    autoload
    配置

yaf,cii,裸写框架(autoload,路由)代码和性能

性能比较

裸写在CPU占用方面和YAF相近,略高,在内存方面更节省。在吞吐量方面和YAF相近,略好。
CI框架会比YAF在CPU方面多耗费10%。吞吐量要差75%

  • 吞吐
    裸写优于yaf,yaf可以比CI提升75%左右
    在php-fpm固定为10个,看处理速度,全部打满4000qps压测。10s预热,30s压测
    我们的框架最大吞吐量是2200/s,平均有970,一共处理了20万
    ci的最大为1850/s。但是会有502和504且有CPU为0的时候,平均只有400,一共处理5万左右,可以看出ci在稳定情况下最大的吞吐量可以达到1600,共处理4万左右
    yaf的最大吞吐量是2280/s。但平均只有670,所以一共处理7万
  • CPU
    php-fpm开2048个,全部绑定到cpu1上, tsung压直到打满CPU,10秒预热+30秒压测
    yaf和我们的框架可以压到600qps.CI到600直接CPU掉底了
    500时,我们的框架略优于YAF.YAF相比于CI要节省至少10个点的CPU使用率
    300时,我们的框架和YAF基本一样,CI还是要高出10个点。

代码

  • yaf

    index.php <?php define('APPLICATION_PATH', dirname(__FILE__)); $performance = getrusage(); $globalPerformStatics['cpu_time_start'] = $performance['ru_utime.tv_sec'] *1000000+ $performance['ru_utime.tv_usec']+$performance['ru_stime.tv_sec'] *1000000+$performance['ru_stime.tv_usec']; $application = new Yaf_Application( APPLICATION_PATH . "/conf/application.ini"); $application->bootstrap()->run(); $performance = getrusage(); $globalPerformStatics['cpu_time_end'] = $performance['ru_utime.tv_sec'] *1000000+ $performance['ru_utime.tv_usec']+$performance['ru_stime.tv_sec'] *1000000+$performance['ru_stime.tv_usec']; var_dump($globalPerformStatics['cpu_time_end']-$globalPerformStatics['cpu_time_start']); ?>   ———————————————————————————————— Bootstrap.php   <?php class Bootstrap extends Yaf_Bootstrap_Abstract {     public function _initRoute(Yaf_Dispatcher $dispatcher) {         $router = Yaf_Dispatcher::getInstance()->getRouter();         $route = new Yaf_Route_Rewrite(             'order/base/passenger/getinfo',             array(                 'controller' => 'Base_Passenger_Getinfo',                 )             );         $router->addRoute('html1asdfd', $route);     }     public function _initView(Yaf_Dispatcher $dispatcher) {         Yaf_Dispatcher::getInstance()->autoRender(false); } }   ———————————————————————————————— 创建controller/Base/Passenger/Getinfo.php   <?php class Base_Passenger_GetInfoController extends Yaf_Controller_Abstract { public function indexAction($name = "Stranger") {     echo "hello";     $orderId = $this->getRequest()->getQuery("order_id");      $model = new SampleModel();             $orderInfo = $model->selectSample($orderId);     var_dump($orderInfo);     return TRUE; } }   ———————————————————————————————— 创建Model   <?php /**  * @name SampleModel  * @desc sample数据获取类, 可以访问数据库,文件,其它系统等  * @author */   class SampleModel {     public function __construct() {     }     public function selectSample($id) {                 $a = $id / 5.314; // 取反正切 0-5.314的变化区间                         $b = 1000 / 1.520837931073;                         return intval((100 / $a) * $b);                             }     public function insertSample($arrInfo) {         return true;     }   }       
  • 裸写

    index.php <?php define('FRAMEPATH', '/home/project/phputil/'); define('APPPATH', '/home/project/order/'); $performance = getrusage();echo 1; $globalPerformStatics['cpu_time_start'] = $performance['ru_utime.tv_sec'] *1000000+ $performance['ru_utime.tv_usec']+$performance['ru_stime.tv_sec'] *1000000+$performance['ru_stime.tv_usec']; $appNameSpace = 'ProjectOrder'; $_GET = array_merge($_GET, $_POST);//fix Android端把$_GET改成$_POST问题 require_once(FRAMEPATH . '/autoload/autoloader.php'); $loader = ProjectAutoloadAutoloader::getLoader(); $loader->addPsr4('ProjectOrder\', APPPATH); require_once(FRAMEPATH . '/framework.php'); $performance = getrusage(); $globalPerformStatics['cpu_time_end'] = $performance['ru_utime.tv_sec'] *1000000+ $performance['ru_utime.tv_usec']+$performance['ru_stime.tv_sec'] *1000000+$performance['ru_stime.tv_usec']; var_dump($globalPerformStatics['cpu_time_end']-$globalPerformStatics['cpu_time_start']); ?>   ———————————————————————————————— config/route.php <?php namespace ProjectOrderConfig; class Route {         public static $routes = array(                     'order/(.+)' => '$1',                 ); }   ———————————————————————————————— helper/order.php <?php namespace ProjectOrderHelper; class Order{     public static function selectSample($id) {           $a = $id / 5.314; // 取反正切 0-5.314的变化区间           $b = 1000 / 1.520837931073;           return intval((100 / $a) * $b);     } }   ———————————————————————————————— phputil   <?php $loader->addPsr4('ProjectFramework\', FRAMEPATH . ''); //全局变量定义(暂时做法,限制性使用) $__uid   = 0; $_startTime = ''; $_redisCount = 0; $_mysqlCount = 0; $_httpRpcCount = 0; $_thriftRpcCount = 0; try {     $params = array('get' => $_GET, 'post' => $_POST);     $routerConfigPath = $appNameSpace . 'ConfigRoute';     $routerConfig = array();     $errorPageConfig = false;     if(class_exists($routerConfigPath)){         if(!empty($routerConfigPath::$routes) && is_array($routerConfigPath::$routes)){             $routerConfig = $routerConfigPath::$routes;         }         if(!empty($routerConfigPath::$showErrorPage)){             $errorPageConfig = $routerConfigPath::$showErrorPage;         }     }     $_startTime = microtime(true);     $router = new ProjectFrameworkBaseRouter($_SERVER['REQUEST_URI'], $routerConfig,$errorPageConfig);     $router->setRoute();     $router->run($params); } catch (InvalidArgumentException $ex) {     $errNo = -1;     $errMsg = strlen($ex->getMessage()) ? $ex->getMessage() : 'system error';   var_dump(array('errno' => $errNo, 'errmsg' => $errMsg)); } catch (Exception $ex) {     $errNo = $ex->getCode();     $errMsg = $ex->getMessage();  var_dump(array('errno' => $errNo, 'errmsg' => $errMsg)); }
  • ci

    config/route.php CI多级目录支持需要自己开发,粗暴的把路由直接打到welcome.php $route['(.+)'] = 'welcome';   ———————————————————————————————— controller/Welcome.php   <?php class Welcome extends CI_Controller {     public function __construct()     {         parent::__construct();         $this->load->model('SampleModel');     }     public function index()     { echo "hello"; $orderId=$this->input->get('order_id');         $orderInfo = $this->SampleModel->selectSample($orderId);   var_dump($orderInfo); return 1; } }   ———————————————————————————————— model/SampleModel.php   <?php class SampleModel extends CI_Model { public function selectSample($id) {                 $a = $id / 5.314; // 取反正切 0-5.314的变化区间                         $b = 1000 / 1.520837931073;                         return intval((100 / $a) * $b);                             }     public function insertSample($arrInfo) {         return true;     } }   

php异步rpc

php协程

php为何不用多线程:

pthreads v3 is restricted to operating in CLI only: I have spent many years trying to explain that threads in a web server just don't make sense, after 1,111 commits to pthreads I have realised that, my advice is going unheeded.
So I'm promoting the advice to hard and fast fact: you can't use pthreads safely and sensibly anywhere but CLI.
Thanks for listening php框架-脚本宝典

curl_mutli

设为非阻塞的socket,调用libcurl的方法。也是select后执行,跟我们php协程处理方式差不多
curl_multi_init
curl_multi_add_handle
curl_multi_select
select有结果后curl_multi_perform // multi_runsingle.一个一个进行,状态流转,从任何一个状态都可以继续执行
当select结束后curl_multi_info_read
curl_multi_remove_handle,curl_multi_cleanup

swoole框架异步和corotine实现

swoole:https://wiki.swoole.com/wiki/...
协程原理:跳堆栈的原理
异步:客户端/mysql/redis/http等。这些只能在cli下调用。不能在fpm中, 异步就是设为非阻塞的socket, 然后设置回调。epoll。一个进程就行了。

自开发并发rpc

http协议封装libcurl.其他协议 状态机+epoll

workerman-thrift

需要分开提供发送和读取两个接口。对发送和读取两个步骤实现异步。先发送一批再读取,不是发完了等待接收再下一个。

总结

以上是脚本宝典为你收集整理的

php框架

全部内容,希望文章能够帮你解决

php框架

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过