3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Organization

「laravel.osaka #14」勉強会まとめ

laravel.osaka とは

laravel.osaka は「laravelおもろいやん!!」をテーマに、Laravelを愛してやまないPHPer や
これからLaravel/PHPをはじめようする人たちで技術交流を進めていこう、という勉強会です。

laravel.osaka - connpass

ハッシュタグは #laravel_osaka

日時・場所

  • 日時:4月23日(火)19:00 ~ 21:00
  • 場所:大阪府大阪市北区同心1丁目11番6号(株式会社 tambourine様)

勉強会内容

[PHP] laravel.osaka #14 - connpass の勉強会の内容をまとめていきます

「Laravelでサービスを作った時にやったこと」

登壇者:@dala00さん
スライド:Laravelでサービスを作った時にやったこと - Speaker Deck
内容:
Qiitaのようなエンジニア向けWEBサービス「Crieit」を作った際のお話

※途中参加につきお話聞けず・・・すみません。。。

「index.phpの処理を追ってみた」

登壇者:@choco14tさん
スライド:index.phpの処理を追ってみた / Dive into index.php - Speaker Deck
内容:

  • index.php
    • この中の
index.php
$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

について処理を追っていく

  • bootstrap/app.php

    • $app = require_once __DIR__.'/../bootstrap/app.php';
    • Applicationインスタンス生成
      • サービスプロバイダ
      • エイリアス
    • インスタンス
  • Container::singleton()

    • Container::build()を呼んでいる
Container\Container.php
    /**
     * Register a shared binding in the container.
     *
     * @param  string  $abstract
     * @param  \Closure|string|null  $concrete
     * @return void
     */
    public function singleton($abstract, $concrete = null)
    {
        $this->bind($abstract, $concrete, true);
    }
  • sharedフラグをtrueにしている

    • Container::bind()
Container\Container.php
    /**
     * Register a binding with the container.
     *
     * @param  string  $abstract
     * @param  \Closure|string|null  $concrete
     * @param  bool  $shared
     * @return void
     */
    public function bind($abstract, $concrete = null, $shared = false)
    {
        // If no concrete type was given, we will simply set the concrete type to the
        // abstract type. After that, the concrete type to be registered as shared
        // without being forced to state their classes in both of the parameters.
        $this->dropStaleInstances($abstract);
        if (is_null($concrete)) {
            $concrete = $abstract;
        }
        // If the factory is not a Closure, it means it is just a class name which is
        // bound into this container to the abstract type and we will just wrap it
        // up inside its own Closure to give us more convenience when extending.
        if (! $concrete instanceof Closure) {
            $concrete = $this->getClosure($abstract, $concrete);
        }
        $this->bindings[$abstract] = compact('concrete', 'shared');
        // If the abstract type was already resolved in this container we'll fire the
        // rebound listener so that any objects which have already gotten resolved
        // can have their copy of the object updated via the listener callbacks.
        if ($this->resolved($abstract)) {
            $this->rebound($abstract);
        }
    }
  • Application::make()
    • サービスプロバイダの遅延読み込み(あれば)
    • 依存オブジェクトの解決
index.php
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
Foundation/Application.php
    /**
     * Resolve the given type from the container.
     *
     * (Overriding Container::make)
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @return mixed
     */
    public function make($abstract, array $parameters = [])
    {
        $abstract = $this->getAlias($abstract);
        if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) {
            $this->loadDeferredProvider($abstract);
        }
        return parent::make($abstract, $parameters);
    }
Container/Container.php
    /**
     * Resolve the given type from the container.
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @return mixed
     */
    public function make($abstract, array $parameters = [])
    {
        return $this->resolve($abstract, $parameters);
    }
  • Container::resolve()
    • 依存オブジェクトの生成
    • 再帰的に依存オブジェクトを生成
    • Container::make()を再呼び出し
Container/Container.php
    /**
     * Resolve the given type from the container.
     *
     * @param  string  $abstract
     * @param  array  $parameters
     * @return mixed
     */
    protected function resolve($abstract, $parameters = [])
    {
        $abstract = $this->getAlias($abstract);
        $needsContextualBuild = ! empty($parameters) || ! is_null(
            $this->getContextualConcrete($abstract)
        );
        // If an instance of the type is currently being managed as a singleton we'll
        // just return an existing instance instead of instantiating new instances
        // so the developer can keep using the same objects instance every time.
        if (isset($this->instances[$abstract]) && ! $needsContextualBuild) {
            return $this->instances[$abstract];
        }
        $this->with[] = $parameters;
        $concrete = $this->getConcrete($abstract);
        // We're ready to instantiate an instance of the concrete type registered for
        // the binding. This will instantiate the types, as well as resolve any of
        // its "nested" dependencies recursively until all have gotten resolved.
        if ($this->isBuildable($concrete, $abstract)) {
            $object = $this->build($concrete);
        } else {
            $object = $this->make($concrete);
        }
        // If we defined any extenders for this type, we'll need to spin through them
        // and apply them to the object being built. This allows for the extension
        // of services, such as changing configuration or decorating the object.
        foreach ($this->getExtenders($abstract) as $extender) {
            $object = $extender($object, $this);
        }
        // If the requested type is registered as a singleton we'll want to cache off
        // the instances in "memory" so we can return it later without creating an
        // entirely new instance of an object on each subsequent request for it.
        if ($this->isShared($abstract) && ! $needsContextualBuild) {
            $this->instances[$abstract] = $object;
        }
        $this->fireResolvingCallbacks($abstract, $object);
        // Before returning, we will also set the resolved flag to "true" and pop off
        // the parameter overrides for this build. After those two things are done
        // we will be ready to return back the fully constructed class instance.
        $this->resolved[$abstract] = true;
        array_pop($this->with);
        return $object;
    }
  • Container::build()

    • インスタンスの生成
    • Reflectionを使って実現
  • Http\kernal::handle()

    • リクエストを受け取ってレスポンスを返す
index.php
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
  • ブートストラッピング

    • config
    • facade
    • service provider
  • 対応したルーティングの処理実行

  • レスポンス返却

Foundation\Http\Kernel.php
    /**
     * Handle an incoming HTTP request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function handle($request)
    {
        try {
            $request->enableHttpMethodParameterOverride();
            $response = $this->sendRequestThroughRouter($request);
        } catch (Exception $e) {
            $this->reportException($e);
            $response = $this->renderException($request, $e);
        } catch (Throwable $e) {
            $this->reportException($e = new FatalThrowableError($e));
            $response = $this->renderException($request, $e);
        }
        $this->app['events']->dispatch(
            new Events\RequestHandled($request, $response)
        );
        return $response;
    }
Foundation\Http\Kernel.php
    /**
     * The bootstrap classes for the application.
     *
     * @var array
     */
    protected $bootstrappers = [
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];

まとめ

  • 実際に処理が行われるまで膨大な処理が実行されている
  • Laravelのコードを読むことは可能なので読んでみましょう

「LaravelでREST API開発(ライブコーディング)」

登壇者:@_mikakaneさん
スライド:なし
内容:

  • 開発環境構築について

    • $ laravel new で環境構築できる
    • $ php artisan serveコマンドでサーバーが立ち上がる
  • Laravel Mixを使用する際はnpmビルドする必要がある

  • Laravel Telescope

    • 上からキャッシュやリクエストを確認できる
  • Factoryでサンプルのユーザーデータが簡単につくれる

  • Str::random()でランダムの文字列を生成される → Str::random()

  • 画面のテストはtests\Featureディレクトリ内にかく

    • テストの際にassertStatus(200)を書いておくだけでもちゃんとレスポンスが返ってくるかの確認ができる
    • テストを実行する際はphpunitコマンドをたたく
    • パスワードを検証する際はHash::check()メソッドを使用する
      • これで認証失敗の場合はabort(403)を返すようにする
    • この反対のメソッドをテストに書いておくと、正常系は200、認証失敗は403を返すということを確認できる
    • RESTAPIを作成するときはpostメソッド等を使用することにより内部的にリクエストを送ることができるのでこれらをつかってテストコードをかく
    • ヘッダを送るときは$this->withHeaderを使う
  • テストコードを書いて実装 いわゆる「テスト駆動開発」

  • @depends メソッド名 とアノテーションを書いてやるとそのテストを実行後でないと実行されない&返り値をそのメソッドの引数に渡せる

    • ログインのテスト実行後、トークンを引数として渡してやると、以降のテストで認証情報を使える

まとめ

  • Laravel Telescopeは便利だが画面の行き来が発生する
  • ほとんどの作業がPhpStorm上で完結する(RESTAPIの開発が可能)

LT枠:20年目のPHPer、laravelと出会う

登壇者:@takujiozakiさん
スライド:なし
内容:

  • 専門学校の教師をしている
  • プログラマー=Javaという認識の生徒が多い
  • 教え子から現場ではLaravelを使うことが多いという話を聞く
    • Laravelを勉強し始めた

おわり

  • 登壇者の方、主催者の方、ありがとうございました&お疲れ様でした!
  • まとめのくせにまとまってないのはすみません。。
  • わかる部分とわからない部分があるのでもっと勉強します

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
3
Help us understand the problem. What are the problem?