标题:PHP7框架之Lumen之Hello World,PHP7下的Lumen (5.5.*)框架之Hello World,如何调用Models下面的数据层,触目了解其MVC思想和取数据成功实践于基于其领悟,学下先进。 出处:向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除 时间:Fri, 13 Jan 2017 15:20:12 +0000 作者:jackxiang 地址:http://jackxiang.com/post/9177/ 内容: 背景:听说Lumen起家是以一个叫av的框架,larvael。以Auth2.0起步,Lumen是精简版本,于是想了解一下。发现居然边TM路由就卡住了,Fuck,不光是我老外也有这个问题,都没有解决,主要是一个Nginx的转写问题,这块在Lumen的文档里写的很垃圾,我都不知这些人是怎么写文档的,有用Apache,有Nginx的就不能写细一点么,说一下原理啥的,关键是Nginx配置文件里面的:location /里面的重写。 From:http://blog.csdn.net/wowkk/article/details/52104689 Lumen 5.5.*版本的Lumen,目录:lumen-clear-edition composer create-project laravel/lumen lumen-clear-edition --prefer-dist "5.5.*" # proc_open, vi ms/survey/bootstrap/app.php require __DIR__.'/../config/providers.php' vi ms/survey/config/providers.php register(Common\Providers\RedisServiceProvider::class); $app->register(Common\Providers\MysqlServiceProvider::class); $app->register(Common\Providers\KafkaServiceProvider::class); $app->register(Common\Providers\EventServiceProvider::class); $app->register(Common\Providers\QueueServiceProvider::class); 注册的文件在: ls ./lumen-clear-edition/common/Providers EventServiceProvider.php MysqlServiceProvider.php RedisServiceProvider.php 启动方法: 启动方法#服务提供者中注册一个视图 composer 则应该在 boot 方法中完成。此方法会在所有其它的服务提供者被注册后才被调用,意味着你能访问已经被框架注册的所有其它服务:https://lumen.laravel-china.org/docs/5.3/providers,ServiceProvider类,和绑定easy_kafka类: lumen-clear-edition/common/Providers/KafkaServiceProvider.php app->bind('easy_kafka',function(){ return new \Common\Service\Kafka\Kafka(); #vi lumen-clear-edition/common/Service/Kafka/Kafka.php 绑定的easy_kafka这个类名在这儿: lumen-clear-edition/common/Facades/Kafka.php }); } } vi lumen-clear-edition/common/Service/Kafka/Kafka.php #自己写这个类的方法。 group(['namespace'=>'Api\V1'], function () use ($router) { $router->post('activity/form', ['uses' => 'ActivityController@form']); use App\Helpers\Client\SurveyClient; public function form(Request $request){ ...... $client = new SurveyClient(); $client->reportInfo($data); } ms/survey/app/Helpers/Client/SurveyClient.php namespace App\Helpers\Client; use Common\Facades\Queue as Queue; #这句引入ms/lumen-clear-edition/common/Facades/Queue.php public function reportInfo($info){ Queue::load('mysql')->push('survey_reportInfo',['class'=>'survey','method'=>'reportInfo','dataKey'=>"survey_reportInfo_{$info['iid']}_{$info['uid']}"],$info); } 类的加载,common文件夹位置: "autoload": { "psr-4": { "App\\": "app/", "Common\\": "common/" } }, #composer dump-autoload --optimize Do not run Composer as root/super user! See https://getcomposer.org/root for details Generating optimized autoload files 生成文件在这儿(挪动一下文件放到新目录,建议重新运行一下这个:composer dump-autoload --optimize,再就是如果有PHP的OPcache得重新启动一下PHP-FPM或关闭掉Opcache,/usr/local/php/etc/php.d/opcache.ini ,opcache.enable=0): ./lumen-clear-edition/vendor/composer/autoload_psr4.php: 'Common\\' => array($baseDir . '/common'), More: 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), 'Cron\\' => array($vendorDir . '/mtdowling/cron-expression/src/Cron'), 'Common\\' => array($baseDir . '/common'), 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'), 'Amp\\' => array($vendorDir . '/amphp/amp/lib'), #find ./ -mtime 0 -type f ./composer.json <== "Common\\": "common/" ./app/Http/Controllers/Api/V1/ActivityController.php ./app/Helpers/Client/SurveyClient.php ./common/Providers/UserServiceProvider.php ./common/Facades/User.php ./common/Services/User/User.php ./config/providers.php composer dump-autoload --optimize改动的: ./vendor/autoload.php ==》return ComposerAutoloaderInit7d1969d6b0c0a5e119f2b7e0932178e2::getLoader(); ./vendor/composer/autoload_psr4.php ./vendor/composer/autoload_static.php ./vendor/composer/autoload_classmap.php ./vendor/composer/autoload_files.php ./vendor/composer/ClassLoader.php ./vendor/composer/autoload_namespaces.php ./vendor/composer/autoload_real.php 访问URL: http://47.93.207.136/activity/survey 最后,这个Provider的类如何使用参考,但写得不是很明白,最新版本的和实际使用并不定一模一样的:http://www.cnblogs.com/cxscode/p/7569856.html 路由:https://lumen.laravel.com/docs/5.4 中文文档:http://laravelacademy.org/laravel-docs-5_4 5.4这个路由,老外写得很简单,这帮人可能是想你去看他的代码吧,有很多人在问: http://www.thinksaas.cn/ask/question/22000/ class KafkaServiceProvider extends ServiceProvider{ return new \Common\Service\Kafka\Kafka(); #lumen-clear-edition/common/Service/Kafka/Kafka.php lumen-clear-edition/common/Service/Kafka/Kafka.php 里: use Kafka\ProducerConfig; use Kafka\ProducerConfig; use Kafka\Producer; use Illuminate\Support\Facades\Config; $this->_config = Config::get('kafka'); 做微服务:/usr/local/nginx/conf/vhosts/ms.conf server{ listen 80 default_server; server_name 10.70.**.142; access_log /data/logs/nginx/ms-access.log main; error_log /data/logs/nginx/ms-error.log warn; root /data/www/ms/; rewrite ^/(survey)/.*$ /$1/public/index.php last; location / { index index.shtml index.html index.htm index.php; } location ~ .*\.(php|php5)?$ { include fastcgi_params; fastcgi_pass unix:/dev/shm/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } server_name 10.70.**.142; root /data/www/ms/; rewrite ^/(survey)/.*$ /$1/public/index.php last; http://10.70.33.140/survey/public/index.php /data/www/ms/survey/public/index.php 路由: /data/www/ms/survey/routes/web.php 一)$app->group(['prefix' => 'private','namespace'=>'Api\V1'], function () use ($app) { $app->get('survey/list', ['uses' => 'SurveyController@list']); http://47.93.207.136/private/survey/list app/Http/Controllers/Api/V1/SurveyController.php 二)$app->group(['namespace'=>'Api\V1'], function () use ($app) { $app->get('activity/survey', ['uses' => 'ActivityController@survey']); http://47.93.207.136/activity/survey app/Http/Controllers/Api/V1/ActivityController.php 里有一行: $client = new SurveyClient(); ./app/Helpers/Client/SurveyClient.php:class SurveyClient{ group(['prefix' => 'private','namespace'=>'Api\V1'], function () use ($router) { $router->get('survey/list', ['uses' => 'SurveyController@list']); $router->group(['namespace'=>'Api\V1'], function () use ($router) { $router->get('activity/survey', ['uses' => 'ActivityController@survey']); 调用层级及配置文件的一个情况,二是如何引入框架目录的入口: ./app/Http/Controllers/Api/V1/SurveyController.php:class SurveyController extends Controller{ /** * 删除互动 */ public function delete(Request $request){ $iid = intval($request->input('iid')); $res = Survey::deleteSurvey($iid);#调用Models return $this->out($res?1:0,$res?"success":"failed"); } 调用Models位置: ./app/Models/Survey.php: public static function deleteSurvey($iid){ table('survey')->where('id',$iid)->update(['state'=>1]); } 配置文件: /data/www/ms/survey/config_production/database.php /data/www/ms/survey/config_production/kafka.php /data/www/ms/survey/config_production/redis.php vi /data/htdocs/lumen.levoo.com/bootstrap/app.php #引入框架目录 require_once __DIR__.'/../vendor/autoload.php'; //实现App命名空间自动注册 $loader = new \Composer\Autoload\ClassLoader(); $loader->setPsr4('App\\',__DIR__.'/../app/'); $loader->register(true); ./bootstrap/app.php:require_once __DIR__.'/../../lumen-clear-edition/vendor/autoload.php'; ====================================================================================== Lumen 中可以使用的 Facades,查看源代码,可用清单如下(https://segmentfault.com/a/1190000002902055): /survey/bootstrap/app.php:$app->withFacades(); $app->withFacades(); ./lumen-clear-edition/vendor/laravel/lumen-framework/src/Application.php: public function withFacades($aliases = true, $userAliases = []) ./vendor/laravel/lumen-framework/src/Application.php public function withAliases($userAliases = []) if (! static::$aliasesRegistered) { static::$aliasesRegistered = true; $merged = array_merge($defaults, $userAliases); foreach ($merged as $original => $alias) { class_alias($original, $alias); } } ========================================================================================== /usr/local/composer/composer.phar global require "laravel/lumen-installer" https://lumen.laravel.com/docs/5.4#server-requirements 下面的: chmod a+x /root/.config/composer/vendor/laravel/lumen-installer/lumen /root/.config/composer/vendor/bin/lumen new lumen.levoo.com /data/htdocs/lumen.levoo.com/blog/routes/web.php 你可以将所有路由都定义在routes/web.php中。最基本的 Lumen 路由接收: http://laravelacademy.org/post/6337.html $app->group(['prefix'=>'test'],function($app){ $app->get("/index",["uses" => "TestController@index"]); }); 【lumen】基础点记录使用:blog.csdn.net/imdingding/article/details/48679359 app/Http/routes.php中进行路由配置可以使用如下路由组的形式,在路由上lumen和laravel有一些区别 $app->group(['prefix' => 'scrollnews','namespace' => 'App\Http\Controllers'],function($app) { $app->get('/','NewsController@showall'); $app->get('/{time}_{newpage}.htm','NewsController@showtime'); $app->get('/{newpage}.htm', 'NewsController@show'); }); http://123.57.252.183/test/index hello Lumen (5.4.5) (Laravel Components 5.4.*) /data/htdocs/lumen.levoo.com/app/Http/Controllers/TestController.php increments('id'); $table->string('make'); $table->string('model'); $table->string('year'); $table->timestamps(); }); } php artisan migrate Migrated: 2017_03_04_161708_create_table_cars migrations记录历史 /car 两个表: id int(10) UNSIGNED make varchar(255) model varchar(255) year varchar(255) create d_attimestamp 问题实践来源:http://www.cnblogs.com/crisenchou/p/6237781.html 打开方法来自:http://www.codesec.net/view/497671.html?winzoom=1 Model这块和Controll层的配置: 1)Controll层, /data/htdocs/lumen.levoo.com/app/Http/Controllers/TestController.php "; print_r($result2); } } 2)Model层:/data/htdocs/lumen.levoo.com/app/Models/User.php "; print_r($result2); */ //view()->exists('user'); return view('test', ['name' => 'jackX','results' => $result]); } } vi /data/htdocs/lumen.levoo.com/resources/views/test.blade.php

Hello, {{ $name }}

Hello, {{ $name2 or 'Default' }}

Hello, {!! $name !!}

Array, {{ $results}}

Array, {!! $results !!}

Blade for each:

@foreach ($results as $user) @endforeach

@foreach ($results as $user) @endforeach

只显示id=1的区块:

@foreach ($results as $user) @break($user->id == 1) @endforeach

模板输出:http://123.57.252.183/test/index Hello, jackX Hello, Default Hello, jackX Array, [{"id":1,"mobile":"1881**65108","fansmobile":"18810322234","followedTime":1211212121},{"id":2,"mobile":"1881**65108","fansmobile":"18810322232","followedTime":121212}] Array, [{"id":1,"mobile":"1881**65108","fansmobile":"18810322234","followedTime":1211212121},{"id":2,"mobile":"1881**65108","fansmobile":"18810322232","followedTime":121212}] Blade for each: This is user 1 This is user 1881**65108 This is user 18810322234 This is user 1211212121 This is user 2 This is user 1881**65108 This is user 18810322232 This is user 121212 用户Id=1,标识一下: This is user 1 This is user 1881**65108 This is user 18810322234 This is user 1211212121 This is user 2 This is user 1881**65108 This is user 18810322232 This is user 121212 只显示id=1的区块: This is user 1 This is user 1881**65108 This is user 18810322234 This is user 1211212121 这个叫Blade的模板引擎解析成PHP的,也就是相当于没有啥大的损耗,如果它的算法还算先进的前提下,位置在: /data/htdocs/lumen.levoo.com/storage/framework/views/9e3b647aebb6a248d1ae42408e87c3fc7f5bc520.php 为什么这么说呢,如下,我在想为何要搞成这样,PHP裸写不也一样么,像Ci框架啥的,思考思考,这样也算是能模板和程序分离罢:

只显示id=1的区块:

addLoop($__currentLoopData); foreach($__currentLoopData as $user): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?> id == 1) break; ?> popLoop(); $loop = $__env->getLastLoop(); ?>

主要是对这个模板有一个大体理解,和Smarty啥的有一个初步了解,参考自: http://laravelacademy.org/post/6780.html ====================================================================== Nginx配置文件: server { listen 80 default_server; server_name 101.200.189.210 lumen.levoo.com; index index.html index.htm index.php; root /data/htdocs/lumen.levoo.com/blog/public; autoindex on; autoindex_exact_size off; autoindex_localtime on; location ~ .*\.(php|php5)?$ { fastcgi_pass unix:/dev/shm/php-fcgi.sock; fastcgi_index index.php; include fastcgi.conf; } location / { try_files $uri $uri/ /index.php?$query_string; #if (!-f $request_filename){ # rewrite ^/(.+)$ /index.php?s=$1 last; # break; #} } access_log /data/logs/nginx/access_lumen_levoo.log; } 上面location / {里被注释掉的也成,只是优雅度不够,这块好像手册有说明,我当时把 try_files $uri $uri/ /index.php?$query_string;放到location ~ .*\.(php|php5)?$ 里了,发现不对。 http://123.57.252.183/foo Hello World 老外: http://stackoverflow.com/questions/32281294/lumen-simple-route-request-doesnt-work 老外也有这个问题: http://laravel.io/forum/05-08-2014-nginx-laravel-routing-shows-404?page=1 主从数据库配置(多台读库配置): http://blog.sina.com.cn/s/blog_9bbafb790102win1.html 基于Lumen搭建一个OAUTH2认证的API框架: http://www.bibihub.com/php/lumen-mobile-api-oauth-2-authentication/ ========DB学习========= 基本使用 注意:如果你想要使用DB门面,应该取消bootstrap/app.php文件中$app->withFacades()调用前的注释 vi bootstrap/app.php 下面这个需要门面: $app->get('/foo', function () use ($app) { $results = app('db')->select("SELECT * FROM levoo_sns_user"); print_r($results); $results = DB::select("SELECT * FROM levoo_sns_user");//这个需要门面 print_r($results); return 'Hello World'; }); 一些报错的日志:SQLSTATE[HY000] [2002] Connection refused grep: ./survey/config_production/config_production: Too many levels of symbolic links ./survey/config_production/app.php: 'lumen_log_path'=>'/data/logs/lumen/survey.log', //框架日志 grep: ./survey/config/config_production: Too many levels of symbolic links ./survey/config/app.php: 'lumen_log_path'=>'/data/logs/lumen/survey.log', //框架日志 tail -f survey.log Next Illuminate\Database\QueryException: SQLSTATE[HY000] [2002] Connection refused (SQL: select count(*) as aggregate from `survey` where `type` = 0 and `user` = 271 and `state` = 0) in /data/www/ms/lumen-clear-edition/vendor/illuminate/database/Connection.php:664 Generated by Jackxiang's Bo-blog 2.1.1 Release