zoukankan      html  css  js  c++  java
  • laravel框架应用和composer扩展包开发

    laravel5.5+


    laravel官方地址

    laravel是目前最流行的php框架,发展势头迅猛,应用非常广泛,有丰富的扩展包可以应付你能想到的各种应用场景,laravel框架思想前卫,跟随时代潮流,提倡优雅代码,自称为“web工匠”,其中的routeblade模板引擎、console、容器以及composer扩展包为业务的开发提供了极大的便利。

    国内目前已经有众多的laravel社区,比如

    当然还有更多可供开发者学习和交流的网站,可以自行google或者百度。

    不过如果看文档的话,建议查看英文网站官网(如果英语允许的话),官网也有一个对应的社区,供开发者问答,不过貌似没有那么活跃,提问题的话也需要有一定的英文基础,至少可以看懂stackoverflow上的问答。

    言归正传,这里会介绍一下laravel5.5的简易上手教程,如果你需要理解laravel框架整体的设计和实现原理的话,MVC、设计模式(尤其是工厂模式)、路由、管道、容器、控制反转、依赖注入等都是必须要理解的,这里并不深入探讨,否则本作者宝宝就要吐血写个系列了,想想都觉着累(经常加班啊没时间啦!)。

    本教程可以让你在短时间内按照123步骤完成一个网站的应用,贯穿laravel各个层级,对于一个刚接触该框架的开发者来说,先应用,后深入,这也是登堂入室的学习方式,何乐而不为呢?

    Ok, Here we go!!!

    前期准备

    1. 安装php7(最好加入环境变量)。可以上官网或者软件包管理工具安装,例如: brew install php7
    2. 安装composer
    3. 安装mysql

    创建laravel项目

    1. 终端运行命令
    
    composer create-project laravel/laravel blog
    
    2. 进入blog文件夹,运行
    
    php -S localhost:80 -t public
    
    3. 浏览器访问 http://localhost
    4. 运行命令 php artisan
    如果3、4步骤运行成功,则一切无碍,可以进行下一步。
    5. 利用你的编辑工具,以sublime为例,打开blog项目,Ctrl+P 找到web.php,写入如下代码,进行路由注册:
    
    Route::get('/test', function () {
        return "<h1>Hi Sunday.</h1>";
    });
    
    这里简单解释一下,路由在routes目录之下,有三个文件:web.phpconsole.phpchannel.php
    其中,web.php是负责网站路由,也就是当php是以http请求的方式运行时才会用到,
    console.php是在命令行运行模式下运行artisan命令的,这个后续会讲到,
    channel.php是广播消息时会用到,这个本篇略过,需要看的可以查看文档
    gethttp请求方式,路由注册时也可以用post/put/delete/patch等,laravel-router还提供了便利的restful风格的路由注册resource方法,可以对后续业务处理增删改查等。
    上述例子为一个匿名函数,其实一般情况下会有路由分组,前缀,中间件(后面会讲到),别名,匹配等的链式调用:Route::prefix('prefix_example')->middleware(['m_exaple_1','m_example_2'])->group(Route_Closure);
    下面给一个完整的示例:
    
    Route::prefix('hi')->middleware(['hi_m'])->namespace('sd')->group(function () {
        Route::post('sunday', 'SundayController@sunday')->name('hi.sunday.post');
        Route::put('sunday', 'SundayController@sunday')->name('hi.sunday.put');
    })
    
    怎么样?laravel路由的注册风格是不是非常友好,非常灵活多变?其中Route也可以使用app('router')访问,app()是一个辅助方法,这个辅助方法在vendorlaravelframeworksrcIlluminateFoundationhelpers.php中,其中也有很多其他好用的辅助方法。app()涉及到容器的思想和facade门面注册,这里不详述。
    6. 访问以下刚刚注册的路由,http://localhost/test
    7. 手动在app/Http/Controllers下新建或命令行生成一个控制器:php artisan make:controller sd/SundayController,这时你会看到app/Http/sd下面有一个SundayController.php,将下面的代码写入:
    
        public function sunday()
        {
            return "Hi sunday";
        }
    
    8. web.php注册路由,并成功访问:
    
    Route::prefix('hi')->namespace('sd')->group(function () {
        Route::get('sunday', 'SundayController@sunday')->name('hi.sunday.get');
    })
    
    9. 中间件,运行命令php artisan make:middleware MyMiddleware,会生成一个标准中间件,打开MyMiddleware.php可以看到里面有两个方法handleterminate
    
    public function handle($request, $next)
    {
        // 上面两个入参,你不用管,这个是laravel路由分发时自动注入的参数,$request是laravel封装的请求对象,IlluminateHttpRequest,你可以获取到所有超级变量的数据,也可以获得对应的一些请求处理方法如session(),getClientIp().
        // 这个方法是在进入Controller之前运行的,目的是对本次请求进行预处理或者校验等。
        app('log')->info('记录一个日志');
    }
    
    public function terminate($request, $response)
    {
        // 这个方法是在请求即将关闭时运行的,可以处理一些响应相关的逻辑。
        app('log')->info('再记录一下日志');
    }
    
    10. 中间件注册,打开app/Http/Kernel.php ,在$middleware中加入
    
    appHttpMiddlewareMyMiddleware::class
    
    11. 查看 storage/logs/laravel.log(如果你config/app.php配置了日志channeldaily,那么应该看到的是日期格式的文件),里面应该有上一步中记录的日志信息,以及对应的日志级别,laravel的日志使用monolog,可以使用多种驱动去记录日志,也可以配置上报策略,实现了loggerinterface接口,符合psr3的规范。
    12. 视图层,在刚刚的方法 SundayController@sunday 中,将返回值改为:
    
        return view('test.test', ['name' => 'sunday', 'testArray' => [1,2,3]]);
    

    在前端模板所在目录 resources/views下建一个目录test,建一个blade模板test.blade.php,代码如:

    ``` @if ($name ) <h1>{{$name}},你好</h1> @else <h1>无名氏,你好</h1> @endif

    @foreach ($testArray as $testNumber)
    <li>{{$testNumber}}</li>
    @endforeach

    
    <blockquote>在控制器返回视图时,第一个参数是以<code>.</code>号表示<code>resources/views</code>下的目录层级的,上面的<code>test.test</code>则表示视图文件是在<code>test/test.blade.php</code>,第二个参数是一个传递给视图层的数组,里面应当是<code>key =&gt; value</code>关联数组,因为在<code>blade</code>模板引擎中,会直接将对应的<code>key</code>转化成一个可使用的变量,在返回给视图之前,如果你定义了视图绑定,如在<code>ComposerServiceProvider</code>中的<code>boot</code>方法中注册了对应的视图绑定的话,那么会先处理这一步,然后再将数据传给目的文件。<br>在这个例子中,<code>test.blade.php</code>得到了参数之后,会通过<code>blade</code>引擎分析模板文件,解析语法,转化成正常的<code>html</code>文本。<br><code>{{$name}}</code>或<code>{!!$name!!}</code>语法相当于<code>&lt;?=$name&gt;</code>,前者为防止xss会过滤掉一些<code>specialchar</code>,后者则会直接输出文本,不安全。<br><code>@if ... @endif</code>则是条件判断语句,行后面可以跟一个简短的<code>php</code>逻辑判断<br><code>@foreach ... @endforeach</code> 轮询数组<br>其他语法请参考 <a href="https://laravel.com/docs/5.6/blade" rel="nofollow noreferrer">官方文档</a>。</blockquote>
    <p>以上的步骤,仅仅是完成了从路由到视图的简单处理,下面看一下数据模型,<code>Model</code>层</p>
    <h5>13. 配置数据库</h5>
    <p><code>database.php</code></p>
    
    

    // config/database.php
    'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'), // 主机
    'port' => env('DB_PORT', '3306'), // 端口
    'database' => env('DB_DATABASE', 'forge'), // 这里需要配置你的数据库
    'username' => env('DB_USERNAME', 'forge'), // 配置你的用户名
    'password' => env('DB_PASSWORD', ''), // 密码
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
    ],

    
    <p><code>.env</code></p>
    ```// .env文件
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=test #这里需要你手动在数据库创建一下数据库
    DB_USERNAME=root #你自己的用户名
    DB_PASSWORD=pwd #你自己的密码
    
    14. 运行artisan命令 php artisan make:auth
    15. 运行artisan命令 php artisan make:migration 创建user表和密码表,进入你的数据库中查看是否创建成功
    16. 这时,打开网站首页,你会看到有一个登录标志,当你注册成功之后,你会看到user表中多了一条数据,表示数据库连接是成功的。
    model可以通过php artisan make:model TestModel来创建,如果你没有特殊要求的话,它会出现在app目录下。
    进入该Model你会看到它继承了一个EloquentModel,这个ORM model可以为你提供多种多样的CURD方法,具体可见文档,在Model里面需要自定义一些属性,例如table、fillable、guards等,支持软删除use SoftDeletes,但对应表中必须要有deleted_at字段。
    你也可以用DB匿名类或者app('db')来得到一个比EloquentModel更加原始的模型对象,这会让你对数据库的操作更加原生,详见 文档

    以上就是对应的MVC使用的简单介绍

    下面,让我们看看console的使用
    1. 终端进入项目目录,运行php artisan可以查看所有可执行命令
    2. 运行 php artisan route:list可以查看已成功注册的路由列表
    3. php artisan make:command NewCommand创建一个新的命令
    4. 打开app/Console/Commands/NewCommand.php,在$signature后定义一个命令的名称如:test:test {--O|op= : 这是我的测试参数},在handle()方法中写入你的逻辑。如:
    
    $this-&gt;info('我第一个命令'); // 会在终端上输出该文本
    $this-&gt;error('我的命令错了'); // 会在终端上输出该文本
    $this-&gt;confirm('确认我的命令?'); // 选择yes/no
    $this-&gt;choice('我还有其他选择:', ["A", "B"]); // 选择一个
    $this-&gt;output-&gt;progress(); //进度条
    echo $this-&gt;option('op'); // 获取所定义参数值
    

    之后,在app/Console/Kernel.php $commands注册命令AppConsoleCommandsTestCommand::class,运行php artisan test:test --op=1,成功输出1,这条命令算是完工了。

    如果你想要加入定时任务,可以将命令加在schedule()中, $schedule->cron("0 0 0 0 0")这里填写crontab的格式。
    你可以运行php artisan schedule:run来执行定时任务
    laravel会在你项目维护或迭代时自动完成定时任务的重启

    composer扩展包

    如果你有心,当你创建一个laravel项目的时候,就会注意到,composer会在项目中创建一个vendor目录,这个目录下保存着各式各样的扩展包,如:laravel/framework、symphony/console、monolog/monolog等,这些扩展包是laravel的宝库,为你的开发提供了极大便利。

    所有的扩展包都需要符合psr4加载规范,通过spl_autoload_register()方法自动加在,composer会生成一个autoload_classmap.php你可以找到所有加载到的类和文件。

    如何开发一个composer扩展包呢?

    1.新建目录test,进入运行 composer init

    这里type一般选择project/librarylicense一般选择MIT协议(一种开源授权协议)

    2.打开composer.json,加入psr4规则:

    
     "autoload": {
        "psr-4": {
            "Name1\Name2\": "name/src/Name" // 这里表示按照psr4规范,对于name/src/Name目录下的所有文件,加载命名空间以Name1\Name2\为前缀的类。
        }
    }
    

    3.创建name/src/Name目录,在Name目录下创建文件NameServiceProvider.php,代码如下:

    &lt;?php
    namespace Name1Name2;
    
    use IlluminateSupportServiceProvider;
    
    class NameServiceProvider extends ServiceProvider
    {
        public function boot()
        {
            require __DIR__ . '/helpers.php';
            log_info('我进来了');
        }
    }
    

    由于log_info()这个方法我们没有定义过,所以可以在helpers.php中进行定义:

    &lt;?php
    
    if (!function_exist('log_info')) {
        function log_info($message) {
            echo $message . PHP_EOL;
        }
    }
    
    

    我们也可以创建一个更深层次的目录,如Handlers,在其下创建一个TestYou.php:

    
    namespace Name1Name2Handlers;
    
    class TestYou
    {
        public function test()
        {
            log_info("test");
        }
    }
    

    创建一个匿名类Facades/Test.php:

    
    namespace Name1Name2Facades;
    
    use IlluminateSupportFacadesFacade;
    
    class Test extends Facade 
    {
        protected static function getFacadeAccessor()
        {
            return "test";
        }
    }
    

    材料已准备完毕,下面开始切菜:

    // NameServiceProvider
    
    public function register () 
    {
        $this-&gt;app-&gt;bind('test', Name1Name2HandlersTestYou::class);
    }
    
    为什么一定要定义匿名类呢?因为laravel框架本身要求就是少去关注工具类的实现,多关注业务本身,所以所有的sdk或者扩展包都在接入时尽量提供便利,其中$this->app->bind()也体现了一个依赖注入控制反转的思想,使得定义了匿名类的,可以在config/app.php中注册相应匿名类TestNameServiceProvider之后可以以极为便利的方式使用,如:Test::test(),或者app('test')->test(),不需要管他们的命名空间。

    上述的扩展包功能已经基本成形,你需要将它放到相应的代码托管仓库中,如githubhttps://packagist.org(推荐),你可以尝试在laravel中使用命令composer require {你的package名字}进行安装。

    后语

    本文由于初次编写,必然有诸多不合理之处,希望读者们多多给出优化意见,以后在文章中会考虑到,大家共同成长,一起发财。

    stay hungry, stay foolish.

    原文地址:https://segmentfault.com/a/1190000015682131

  • 相关阅读:
    解析包含空格的字符串
    机器学习实战之Logistic回归
    复杂的数据类型
    k-近邻算法
    C&C++
    位运算
    文件操作
    结构体与共用体
    预处理-04-#if defined和#if !defined
    预处理-03-文件包含、条件编译、小结
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9979814.html
Copyright © 2011-2022 走看看