20200215のlaravelに関する記事は7件です。

twitterの情報発信を助けるWebサービス「EMOEMO」やっと公開です!

EMOEMOはこちら

はじめに

こんにちはてらです!:relaxed:
簡単に自己紹介をするとごみくずプログラミング初学者です。(3ヶ月目)
現在個人開発中のWEBサービス(EMOEMO)をデプロイする予定だったのですが、想定外のバグが発生し、
デプロイはもう既にしているのですが公開できない状態に陥りました。やっと修正を終えたのでお披露目したいと思います。
では早速!

EMOEMO:↓LP部分
スクリーンショット 2020-02-11 17.37.25.png

目次

  • EMOEMOとは?別記事で紹介しています。こちらから
  • 一番大変だった所
  • 二番目に大変だった所
  • 課題点
  • 今後の予定

一番大変だった所 !加筆予定!

tweetを送信するだけじゃなく、画像も持たせることができたらより良いと思い実装しようと試みました。この機能の実装は闇が深く一番大変でした。どう大変だったのかについて書くとこれだけで、読みたくなくなるような分量になってしまいます。ですので、あとでコード等は使わずに図でこんなことしてるよ!っていうのを紹介がてらしてみようと思います。

二番目に大変だった所

自分のPC(ローカル)の中で、動かしている状態から実際にサーバー(heroku)にアップロード(デプロイ)をすると今まで使えていた便利機能(ライブラリ)が読み込まれなかったり、画面がうまく表示されなかったりして、滅茶苦茶大変でした。少し具体的に話すとtwitterキーを受け取れてはいるのですがそれをデータベースに保存できなくてコードを変更しました。

課題点

とにかく画面のデザイン(フロントエンド)がゴミカスレベルなのでまともになるように色々手を加えていこうと思っています。その間に皆さんに使ってもらって、こんな機能あったら良いなみたいな要望があったらQiitaのコメントでもtwitterのDMでも良いのでメッセージください!
使ってみてもらって感想までもらえたら僕は嬉しいです!

Twitterアカウント

今後の予定

  • 見た目やボタンの配置(フロントエンド周り)の実装をする
  • 皆さんの反応次第で機能の追加
    • 画像の削除機能の追加

この2点を主軸にして開発を進めていこうと思います。画像の削除機能については必須だと思うので実装します!

最後に!!!!!

もし最後まで読んでくださっている方がいたら良いねをお願いします!よろしくお願いします!
またね!

EMOEMOはこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel で Fat Controller を防ぐ 5 つの Tips

この記事について

Laravel は Policy や FormRequest など、Controller を補佐するモジュールを多く提供しているので Fat Controller になりにくいとは思いますが、それでもときどき Fat Controller に出くわすことがありますので、それらを防ぐために使えるテクニックというか、Tips を5つばかり紹介したいと思います。

はじめに

Fat Controller とは?

簡潔にいえば、行数が多く(個人的には Controller だとひとつのメソッドが NCLOC で 50 行を超えると Fat 感を感じます、みなさんはいかがでしょうか)、行数が多いがために処理の流れを追うことが難しく、しばしば不具合の原因になるクラスのことをいうのだと思います。本記事では、ただ行数が多いというだけでなく、複数のメソッドで処理が重複していたり、メソッドの中で条件分岐が発生したりして、ひとつの変更が他の部分に及ぼす影響を検知しづらい状態にあるコントローラーを想定しています。

巨大なクラスであっても、そこに含まれるデータや関数が高凝集・低結合であれば問題ないと考えます。大事なのは「不具合の原因になる」ということであって、すべての巨大なクラスが悪である、ということではないと思っています。

Fat Controller の問題点

  • 【長すぎるメソッド】ひとつひとつのメソッドが長く、処理の流れを追うことが難しい。それによって、局所的な変更が処理全体に影響することがあり、予期せぬ不具合が発生することがある
  • 【処理の重複】Controller 間で処理が重複することによって、仕様変更によるコードの変更が漏れ、予期せぬ不具合が発生することがある
  • 【単一責任原則違反】複数のパターンを同一の Controller で処理することによって、ひとつのパターンに関する変更が他のパターンへ影響することがあり、それによって予期せぬ不具合が発生することがある

Fat Controller になる主な要因として、Model 層が貧弱すぎる、ということが考えられます。本来 Model に書くべき処理を Controller に書いてしまっており、結果的に可読性が悪くなったり、ひとつのユースケースに対する変更が他のユースケースに影響を及ぼしたり、Controller 間でのコピペコードを量産したり、ということが起きます。

Fat Controller を防ぐ 5 つの Tips

  1. リクエストのデータを処理する関数は FormRequest に書く
  2. レスポンスのデータを処理する関数は ViewModel あるいは Resource に書く
  3. シングルアクションコントローラーにする
  4. 複数の Controller に分離する
  5. UseCaseInteractor を使う

1. リクエストのデータを処理する関数は FormRequest に書く

public function search(Request $request) {
    if (isset($request->query('name'))) {
        $whereParams['name'] = $request->query('name');
    }
    return User::where($whereParams)->get();
}

みたいなリクエストパラメータの有無によって処理が分岐していくパターンです。上の例はひとつだけですが、これがずらっとあったり、if 文の中の条件が複雑になってくるとだいぶ読みにくくなってきます。

そこで、これらの処理は FormRequest 側へ移します。

// Controller
public function search(SearchUserRequest $request) {
    return User::where($request->filters())->get();
}

// FormRequest
public function filters(): array {
    $filters = [];
    if (isset($this->query('name'))) {
        $filters['name'] = $this->query('name');
    }
    return $filters;  
}

処理をただ他のクラスに移しただけじゃねーか、と思われるかもしれませんが、FormRequest へ移動することのメリットは、モデルに渡す入力パラメータの構築にのみ注力できる、ということで、たとえば、バリデーションルールは FormRequest に書いてあるでしょうから、入力パラメータが増えたりしたときに、FormRequest のみを変更すればよい状態にしておくと、変更漏れが起こりにくいんじゃないかと思います。また、複数のモデルに対して連続して処理するような変更が起こった場合にも、どれがどのモデルに関連するパラメータなのか、区別がつきやすくなると思います。

public function search(SearchUserRequest $request) {
    $users = User::where($request->userFilters())->get();
    $anotherModels = AnotherModels
        ::whereIn('user_id', $users->pluck('id'))
        ->where($request->anotherFilters())
        ->get();
    return ['users' => $users, 'anotherModels' => $anotherModels];
}

2. レスポンスのデータを処理する関数は ViewModel あるいは Resource に書く

public function index() {
    $users = User::where(...)->get();
    foreach ($users as $user) {
        $user->full_name = $user->family_name . ' ' . $user->given_name;
    }
    return view('user.index', compact('users'));
}

上の例はゲッターでやるほうがいいかなと思いますが、いい例を思いつかなかったのでご容赦を。

要は、Controller で受け取った Model からの戻り値を、View に渡す前に加工しなければならないケース、ということです。

// Controller
public function index() {
    $users = User::where(...)->get();
    $viewModel = new UsersViewModel($users);
    return view('user.index', ['users' => $viewModel->users()]);
}

// ViewModel
public function __construct(array $users) {
    $this->users = $users;
}
public function users(): array {
    return array_map([$this, 'transform'], $this->users);
}
private function transform(User $user): array {
    return [
        'id'   => $user->id,
        'name' => $user->family_name . ' ' . $user->given_name,
    ];
}

transform が返すのはオブジェクトにしてもいいでしょう。変換ロジックを書き換えたければ、 Controller 側で差し替えられるようにすると柔軟性が出ます。

// Controller
$viewModel = new UsersViewModel($users, new SummaryUserTransformer);

// ViewModel
public function __construct(array $users, UserTransformerInterface $transformer = null) {
    $this->users = $users;
    $this->transformer = $transformer ?? new DefaultUserTransformer;
}
public function users(): array {
    return array_map($this->transformer, $this->users);
}

// Transformer
public function __invoke(User $user) {
  return [
      // ...
  ];
}

3. シングルアクションコントローラーにする

シングルアクションコントローラーとは、 __invoke メソッドを持つ、特定のルーティングと対になる Controller クラスのことです。

ルーティングの書き方に特徴があります。

通常は Route::get('/', 'HomeController@index') のように @ の前にクラス名、後にメソッドを書きますが、シングルアクションコントローラーの場合は Route::get('/', 'HomeController') のようにクラス名のみ指定します(呼び出し時には自動的に __invoke が呼ばれます)。

いわゆる CRUD と呼ばれる処理は、 index/create/store/show/edit/update/delete の中から必要なメソッドを選択して使えばいいですが、それ以外のメソッドは、シングルアクションコントローラーにしておくと、クラスがスッキリすると思います。

4. 複数の Controller に分離する

複数の異なるユースケースを1つのアクションメソッドにまとめてしまうと、パターンによる条件分岐が必要になるため、Fat Controller になりがちです。

もし、Controller 内に、リクエストに応じて処理を分ける、みたいな条件分岐があるようであれば、複数の異なるユースケースをまとめてしまっている可能性があるので、分離できないか検討してみます。

public function __invoke(SearchUserRequest $request) {
    if ($request->is_special) {
        $users = User::searchSpecial($request->specialFilters())->get();
    } else {
        $users = User::search($request->filters())->get();
    }
    // ...
}

これを2つの Controller に分離してしまいます。

// SpecialContext\SearchUserController
public function __invoke(SearchUserRequest $request) {
    $users = User::searchSpecial($request->filters())->get();
    // ...
}
// GenericContext\SearchUserController
public function __invoke(SearchUserRequest $request) {
    $users = User::search($request->filters())->get();
    // ...
}

必要なら Model も分けてしまってもいいかもしれません。

// SpecialContext\SearchUserController
// use SpecialContext\User
public function __invoke(SearchUserRequest $request) {
    $users = User::search($request->filters())->get();
    // ...
}
// GenericContext\SearchUserController
// use GenericContext\User
public function __invoke(SearchUserRequest $request) {
    $users = User::search($request->filters())->get();
    // ...
}

クラスは同じで「別のアクションメソッドに分離する」というのもオッケーですが、CRUD 以外はシングルアクションコントローラーにする、というルールにするなら、Controller を分けることになるでしょう。

5. UseCaseInteractor を使う

UseCaseInteractor はクリーンアーキテクチャの一部で、アプリケーションへの入力(リクエスト)を受け取って中核となる処理を行い、ビュー(あるいは API レスポンス)へのアウトプットを生成するクラスです。

参考)Laravelでクリーンアーキテクチャ - Qiita #UseCaseInteractor

上の例では UseCaseInteractor は値を戻さず、Middleware のプロパティに直接渡す方式を取っていますが、本記事ではそのまま戻すようにしています(名前も簡略化して UseCase としています)。

// Controller
public function __invoke(SearchUserUseCase $useCase, SearchUserRequest $request) {
    $users = $useCase->invoke($request->filters());
    $responder = new UsersResponder($users);
    return $responder->createResponse();
}
// UseCase
public function invoke(array $filters) {
    return User::where($filters)->get();
}
// Responder with Blade view
public function createResponse() {
    $viewModel = new UsersViewModel($this->users, new SummaryUserTransformer);
    return view('user.index', ['users' => $viewModel->users()]);
}
// Responder with API resource
public function createResponse() {
    return UserResource::collection($this->users);
}

UseCase 内に処理を閉じ込めることで、Controller をスリムに保つことができます。このクラスに渡すデータは、HTTP の世界の情報はプリミティブなデータ、あるいはドメインオブジェクトに変換しておくのがいいと思います。

おわりに

いかがでしたでしょうか。例がシンプルすぎていまいちピンとこないかもしれませんが、Fat Controller を解消したいとお悩みの方の一助になれば幸いです。

他にも Fat Controller 解消法をお持ちの方、コメント欄にて教えていただけると大変助かります :bow:

次回は「Laravel で Fat Model を防ぐ 5 つの Tips」をお送りしたいと思います。

2020-02-17 10:38 追記
大事なことが抜けていたので補遺を書きました。
Laravel で Fat Controller を防ぐもうひとつの Tip - Qiita
追記ここまで

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

LaravelのFormRequestでControllerをスマートに書いてみよう。

概要

Laravel:FormRequestの実装方法とメリット

前提

Laravelを初めて触る人、他のフレームワークを触ってMVCでの書き方が理解できていることを前提にお話を進めていきます。

また、Laravelというフレームワークに初めて触ったであろう人を前提に書くのですでに知識がある方には物足りない可能性がございます。

ご了承ください。

FormRequestって何?

プログラミングでバリデーションをすることは、開発をする上で必須の知識であることは何か1つでも開発したことあれば理解できるでしょう。

しかし、このバリデーションは同じ言語だとしてもフレームワークによって当然変化していきます。
例えば同じPHPのフレームワークであるCakePHPを例に挙げるとモデル内に記述していきます。

Hoge.php
class Hoge extends AppModel {
    public $validate = array(
        'login' => 'alphaNumeric',
        'email' => 'email',
        'born'  => 'date'
    );
}

CakePHP 2.x Cookbook データバリデーション
このような記述ですね。

これがLaravelだとどうなるのでしょうか?
参考書などで紹介されているバリデーションは、Controller内で行っているものが多いですね。
例えばこのような感じです。

HogeController.php
public function fuga(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required',
        'body' => 'required',
    ],[
        'title.required' => 'タイトルは必須です。',
        'body.required'  => 'bodyは必須項目です。',
    ]);

}

Laravel 5.5 バリデーション

これが参考書などによく掲載されているパターンで
use Illuminate\Http\Request;
によってRequestクラスが外部注入(別の場所で用意されている武器を身につけるイメージです)されhoge.blade.phpから送られてきたformの値などをバリデーションしています。

豆知識

public function fuga(Request $request)

この部分は外部で記述されたインスタンス(Requestという物の素のイメージ)を$requestという引数に割り当てることでコントローラーの中でのnewを使ったインスタンスの作成を無くしています。

HogeController.php
public function fuga(Request $request)
{
    /*引数に宣言することで
    $request = new Reqeust();
    これを書く必要が無くなります!!*/
}

ここまでだと「この書き方でも問題ないんじゃない?」と思う方もいるかもしれません。
しかし、仮にサービスを開発していく中でバリデーションしなければいけないformが100個(現実的ではありませんがわかりやすく)あった場合どうなるでしょう?

気づいている方もいるかと思いますがバリデーションの項目を記述するだけでメソッド1つだけで100行以上になることになりますよね。メッセージも全部設定したら300行も余裕ですね(笑)
処理としては問題ないけど、、、という感じです。

ではどうしていくべきなのか。ここでFormRequestの登場です。

コマンドで作成

   php artisan make:request XXXXRequest

XXXX の部分は任意で好きな名前にしてください。
このコマンドで作成されたXXXXRequestは app/Http/Requests の配下に作成されます。
開いてみると

app/Http/Requests/XXXXRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class XXXXRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}
public function authorize()
    {
        //return false; アクセスに制限をかけない場合はtrueに変更でしましょう
          return true;
    }

次にバリデーションのルールを書いていきます。
場所は

    public function rules()
    {
        return [
            'title' => 'required',
            'body' => 'required',
        ];
    }
}

先ほどのバリデーションをこのように定義づけてあげるだけOKです!
同じくエラーメッセージもmessagesメソッドを増やしてあげて

    public function messages(){
        return [
            'title.required' => 'タイトルは必須です。',
            'body.required'  => 'bodyは必須項目です。',
        ];
    }

}

これで完璧です?

全体としてみて挙げるとこんな感じです。

app/Http/Requests/XXXXRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class XXXXRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required',
            'body' => 'required',
        ];
    }

    public function messages(){
        return [
            'title.required' => 'タイトルは必須です。',
            'body.required'  => 'bodyは必須項目です。',
        ];
    }
}

いい感じですね。これだけでバリデーションをコントローラーから分離させることに成功しました。

FormRequestを実装したことによって生じるメリットは以下の通りになります。

  • 同じ内容でバリデーションを行いたいときに使い回しが可能。

  • コントローラーでのバリデーションがなくなるため可読性が高まる。

  • 独自のバリデーションを作成するなどの工夫がしやすい。

  • メソッドの前にFormRequestを通過するため毎回エラー時にメソッドを通らなくてよくなる。

作成したFormRequestの使用方法

早速作成したFormRequestを使用していきましょう。使用方法は簡単です。
先ほどのメソッドのRequest部分を作成したXXXXRequestに名前を変更します。

HogeController.php
    use App\Http\Requests\XXXXRequest; //忘れないように注意!!


    public function fuga(XXXXRequest $request) {
        // バリデーション通過後の処理
    }

余裕ですね?

まとめ

FormRequestは一度知れば簡単な基礎でありながらも開発時の可読性など大事な部分に直結する技術です。

この記事を読めば誰でも実装出来るよう書いたつもりですが、ご指摘ありましたらよろしくお願い致します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SwiftMailerでメールが送信できない。 Expected response code 354 but got code "554", with message "554 5.5.1・・・

local.ERROR: Expected response code 354 but got code "554", with message "554 5.5.1 Error: no valid recipients

これに遭遇した時は、メールアドレスを別のサーバで取得したメールアドレスのSMTP設定をして試してみて下さい。

取り立てドメイン、作り立てのメールアドレスだからいけないのかわかりません。
別サーバのメールアドレス変えたら、送信が出来ました。
システム側のバグではないです。バグの原因を調べる時間が喰われるのって本当やだよね。

でわ、また。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac OS 10.15.2】Larabel入れようとしたら詰まった話

初めてMacにLarabel入れようとしたら普通に詰まったので共有します。

経緯

・Homebrewにて、MacにPHPをインストールした。
・ComposerをMacに入れてパスを通した
・以下のコマンドを入力したところで問題発生

composer global require laravel/installer

問題

エラーコード

まずはこんなエラーコードが出ました。

mbp:~ 【ユーザーネーム】$ composer global require laravel/installer
Changed current directory to /Users/【ユーザーネーム】/.composer

Using version ^3.0 for laravel/installer
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/installer v3.0.1 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - laravel/installer v3.0.0 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - Installation request for laravel/installer ^3.0 -> satisfiable by laravel/installer[v3.0.0, v3.0.1].

行なった対処1

まずはLarabelをインストールするときに、どこのPHPを見ているのか確認

コマンド:which php
結果:/usr/bin/php

ここからわかること

・パスがMac標準PHPのものになっているらしい。
・どうやら標準PHPには「zip」らしきものが無いっぽい。
・/usr/bin/phpではなく、/usr/local/opt/phpを見て欲しいのに。

行なった対処2

コマンド:brew install php@7.3
結果:
Warning: php@7.3 7.3.14 is already installed and up-to-date
To reinstall 7.3.14, run `brew reinstall php@7.3`

ここからわかること

・もうすでにhomebrewでのPHPインストールは終わっている。

行なった対処3

コマンド:brew install php@7.3
【結果】
==> Reinstalling php@7.3 
==> Downloading https://homebrew.bintray.com/bottles/php@7.3-7.3.14.catalina.bottle.tar.gz
Already downloaded: /Users/【ユーザーネーム】/Library/Caches/Homebrew/downloads/42f5213d06a0456cf231786c8bf93b8fe340b153e0467babad9e5a0ca2935832--php@7.3-7.3.14.catalina.bottle.tar.gz
==> Pouring php@7.3-7.3.14.catalina.bottle.tar.gz
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_ini /usr/local/etc/php/7.3/php.ini syst
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_dir /usr/local/share/pear@7.3 system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set doc_dir /usr/local/share/pear@7.3/doc syste
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set ext_dir /usr/local/lib/php/pecl/20180731 sy
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set bin_dir /usr/local/opt/php@7.3/bin system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set data_dir /usr/local/share/pear@7.3/data sys
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set cfg_dir /usr/local/share/pear@7.3/cfg syste
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set www_dir /usr/local/share/pear@7.3/htdocs sy
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set man_dir /usr/local/share/man system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set test_dir /usr/local/share/pear@7.3/test sys
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_bin /usr/local/opt/php@7.3/bin/php syst
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear update-channels
==> Caveats
To enable PHP in Apache add the following to httpd.conf and restart Apache:
    LoadModule php7_module /usr/local/opt/php@7.3/lib/httpd/modules/libphp7.so

    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>

Finally, check DirectoryIndex includes index.php
    DirectoryIndex index.php index.html

The php.ini and php-fpm.ini file can be found in:
    /usr/local/etc/php/7.3/

php@7.3 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have php@7.3 first in your PATH run:
  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

For compilers to find php@7.3 you may need to set:
  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"


To have launchd start php@7.3 now and restart at login:
  brew services start php@7.3
Or, if you don't want/need a background service you can just run:
  php-fpm
==> Summary
?  /usr/local/Cellar/php@7.3/7.3.14: 521 files, 77MB

ここからわかること

・インストールは完了している。
よく見ると・・・。

php@7.3 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have php@7.3 first in your PATH run:
  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

For compilers to find php@7.3 you may need to set:
  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"

解決策

※このコマンドをこのまま入力しても良いですが、記事が古くなっている可能性があるので上記コマンドを入力しつつ自分の環境で何が起こっているのかを確認してください。

  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"

この4つのコマンドを記入後、

$ source ~/.bash_profile

このコマンドを入力したら、無事Larabelインストールが出来るようになりました。
めでたし!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac OS 10.15.2】Laravel入れようとしたら詰まった話

初めてMacにLaravel入れようとしたら普通に詰まったので共有します。

経緯

・Homebrewにて、MacにPHPをインストールした。
・ComposerをMacに入れてパスを通した
・以下のコマンドを入力したところで問題発生

composer global require laravel/installer

問題

エラーコード

まずはこんなエラーコードが出ました。

mbp:~ 【ユーザーネーム】$ composer global require laravel/installer
Changed current directory to /Users/【ユーザーネーム】/.composer

Using version ^3.0 for laravel/installer
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/installer v3.0.1 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - laravel/installer v3.0.0 requires ext-zip * -> the requested PHP extension zip is missing from your system.
    - Installation request for laravel/installer ^3.0 -> satisfiable by laravel/installer[v3.0.0, v3.0.1].

Laravelをインストールするときに、どこのPHPを見ているのか確認

コマンド:which php
結果:/usr/bin/php

ここからわかること

・パスがMac標準PHPのものになっているらしい。
・どうやら標準PHPには「zip」らしきものが無いっぽい。
・/usr/bin/phpではなく、/usr/local/opt/phpを見て欲しいのに。

HomebrewでPHPをインストール出来ているかを確認

コマンド:brew install php@7.3
結果:
Warning: php@7.3 7.3.14 is already installed and up-to-date
To reinstall 7.3.14, run `brew reinstall php@7.3`

ここからわかること

・もうすでにhomebrewでのPHPインストールは終わっている。

PHPを念のため再インストール

コマンド:brew reinstall php@7.3
【結果】
==> Reinstalling php@7.3 
==> Downloading https://homebrew.bintray.com/bottles/php@7.3-7.3.14.catalina.bottle.tar.gz
Already downloaded: /Users/【ユーザーネーム】/Library/Caches/Homebrew/downloads/42f5213d06a0456cf231786c8bf93b8fe340b153e0467babad9e5a0ca2935832--php@7.3-7.3.14.catalina.bottle.tar.gz
==> Pouring php@7.3-7.3.14.catalina.bottle.tar.gz
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_ini /usr/local/etc/php/7.3/php.ini syst
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_dir /usr/local/share/pear@7.3 system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set doc_dir /usr/local/share/pear@7.3/doc syste
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set ext_dir /usr/local/lib/php/pecl/20180731 sy
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set bin_dir /usr/local/opt/php@7.3/bin system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set data_dir /usr/local/share/pear@7.3/data sys
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set cfg_dir /usr/local/share/pear@7.3/cfg syste
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set www_dir /usr/local/share/pear@7.3/htdocs sy
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set man_dir /usr/local/share/man system
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set test_dir /usr/local/share/pear@7.3/test sys
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear config-set php_bin /usr/local/opt/php@7.3/bin/php syst
==> /usr/local/Cellar/php@7.3/7.3.14/bin/pear update-channels
==> Caveats
To enable PHP in Apache add the following to httpd.conf and restart Apache:
    LoadModule php7_module /usr/local/opt/php@7.3/lib/httpd/modules/libphp7.so

    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>

Finally, check DirectoryIndex includes index.php
    DirectoryIndex index.php index.html

The php.ini and php-fpm.ini file can be found in:
    /usr/local/etc/php/7.3/

php@7.3 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have php@7.3 first in your PATH run:
  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

For compilers to find php@7.3 you may need to set:
  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"


To have launchd start php@7.3 now and restart at login:
  brew services start php@7.3
Or, if you don't want/need a background service you can just run:
  php-fpm
==> Summary
?  /usr/local/Cellar/php@7.3/7.3.14: 521 files, 77MB

ここからわかること

・インストールは完了している。
よく見ると・・・。

php@7.3 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.

If you need to have php@7.3 first in your PATH run:
  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

For compilers to find php@7.3 you may need to set:
  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"

解決策

※このコマンドをこのまま入力しても良いですが、記事が古くなっている可能性があるので上記コマンドを入力しつつ自分の環境で何が起こっているのかを確認してください。

  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

  export LDFLAGS="-L/usr/local/opt/php@7.3/lib"
  export CPPFLAGS="-I/usr/local/opt/php@7.3/include"

この4つのコマンドを記入後、

$ source ~/.bash_profile

このコマンドを入力したら、無事Laravelインストールが出来るようになりました。
めでたし!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

twitterの情報発信を助けるWebサービス「EMOEMO」の延期理由について。

EMOEMOはこちら

はじめに


初めまして!てらって呼んでください:relaxed:
簡単に自己紹介をするとごみくずプログラミング初学者です。(3ヶ月目)
現在個人開発中のWEBサービス(EMOEMO)をデプロイする予定だったのですが、想定外のバグが発生し、
デプロイはもう既にしているのですが公開できない状態です。現状のバグと今後の対策案について考えてみましたので、報告できればと思います。

現状のバグ&対策案

  • 全てのログインしているユーザーがツイートを送信しても僕のアカウントにツイートされてしまう。

どうやらtwitter認証周りのコードが悪さをしているような気がするので、その辺りから攻めてみようかと思っております。苦しい戦いになりそうです。

嘆き

画像の投稿関連の実装にもかなり時間をかけていて結構ギリギリでも実装できたのでこの勢いでと思ったのですが、
やはり、簡単にはいかないようです。引き続きどうにか頑張って、修正して使えるようにして見せるので待っていてください!

EMOEMOの新規実装機能

  • 画像投稿機能
  • 一覧ソート表示機能

ソート機能は大した事はなかったのですが、画像を投稿する実装がめちゃくちゃ大変でした。4日くらいかかりました。
具体的にどのような感じの実装になったかというと↓のような感じです。投稿するのが難しく、できても編集できるようにする機能の実装が滅茶苦茶大変でした。最終的に投稿した画像を編集できるようにするためのコード200行くらいになりました。汗

alt

フロントは全然いじってないのですが基本的な機能を実装し終えて、デプロイし、皆さんに使ってもらっている間に手を入れようと思っています。

引き続きEMOEMOをよろしくお願いします。(まだデプロイして無いですが...)

最後に

もし最後まで読んでくれた方がいたら、いいね!をおねがします!

EMOEMOはこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む