20210412のlaravelに関する記事は8件です。

Laravel Sail 使って開発したかっただけなのに......

はじめに laravel でコンテナ開発を一瞬で始められると噂のLaravel Sail 使って意気揚々と開発始めたらハマった。。。 ちなみに下記記事参考にしました。 やりたかったこと ただ Laravel 使ってdocker環境で開発したかっただけなのに。。。 まずは4コマンドでLaravelアプリ作成 terminal $ curl -s https://laravel.build/larademo | bash $ cd larademo $ ./vendor/bin/sail up -d $ ./vendor/bin/sail php artisan vendor:publish --tag=serverless-config docker-compose.yml docker-compose.yml version: '3' services: laraveldemo: # コンテナ名は変更した。元々はlaravel.test build: context: ./vendor/laravel/sail/runtimes/8.0 dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' image: sail-8.0/app ports: - '${APP_PORT:-80}:80' environment: WWWUSER: '${WWWUSER}' LARAVEL_SAIL: 1 volumes: - '.:/var/www/html' networks: - sail depends_on: - mysql # - pgsql # - redis # - selenium # selenium: # image: 'selenium/standalone-chrome' # volumes: # - '/dev/shm:/dev/shm' # networks: # - sail mysql: image: 'mysql:8.0' ports: - '${FORWARD_DB_PORT:-3306}:3306' environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_USER: '${DB_USERNAME}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' volumes: - 'sailmysql:/var/lib/mysql' networks: - sail healthcheck: test: ["CMD", "mysqladmin", "ping"] # pgsql: # image: postgres:13 # ports: # - '${FORWARD_DB_PORT:-5432}:5432' # environment: # PGPASSWORD: '${DB_PASSWORD:-secret}' # POSTGRES_DB: '${DB_DATABASE}' # POSTGRES_USER: '${DB_USERNAME}' # POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' # volumes: # - 'sailpostgresql:/var/lib/postgresql/data' # networks: # - sail # healthcheck: # test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"] # redis: # image: 'redis:alpine' # ports: # - '${FORWARD_REDIS_PORT:-6379}:6379' # volumes: # - 'sailredis:/data' # networks: # - sail # healthcheck: # test: ["CMD", "redis-cli", "ping"] # memcached: # image: 'memcached:alpine' # ports: # - '11211:11211' # networks: # - sail # mailhog: # image: 'mailhog/mailhog:latest' # ports: # - '${FORWARD_MAILHOG_PORT:-1025}:1025' # - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025' # networks: # - sail networks: sail: driver: bridge volumes: sailmysql: driver: local # sailpostgresql: # driver: local # sailredis: # driver: local 環境によってenvファイルを分ける 詳しくはこちら デフォルトで入っている.env ファイルは使わずに、 .env.local .env.stg .env.prod と環境ごとに分けた。 よし、フロントはVuetify使いたいしインストールするかぁ。。 $ ./vendor/bin/sail npm install vuetify ERROR: No such service: laravel.test あれ??? 他のモジュールをインストールしようとしても、composer require しても同じ結果だった。 原因は./vendor/laravel/sail/bin/sail にあった。 知らんかったことその1 .env ファイルを読み込みにいく設定がデフォだった。 ./vendor/laravel/sail/bin/sail (省略) if [ -f ./.env ]; then source ./.env fi (省略) 知らんかったことその2 環境変数APP_SERVICEを設定&&コンテナ名と同じにする必要がある ./vendor/laravel/sail/bin/sail (省略) # Define environment variables... export APP_PORT=${APP_PORT:-80} export APP_SERVICE=${APP_SERVICE:-"laravel.test"} # .envファイルにはAPP_SERVICEがデフォで定義されないので自動的にlaravel.test export DB_PORT=${DB_PORT:-3306} export WWWUSER=${WWWUSER:-$UID} export WWWGROUP=${WWWGROUP:-$(id -g)} (省略) ./vendor/laravel/sail/bin/sail (省略) if [ $# -gt 0 ]; then # Source the ".env" file so Laravel's environment variables are available... if [ -f ./.env ]; then source ./.env fi # Proxy PHP commands to the "php" binary on the application container... if [ "$1" == "php" ]; then shift 1 if [ "$EXEC" == "yes" ]; then docker-compose exec \ -u sail \ "$APP_SERVICE" \ # ここで$APP_SERVICEが呼ばれる php "$@" else sail_is_not_running fi (省略) 解決策 APP_SERVICEの設定 .env.local APP_SERVICE="laraevldemo" # ちなみに "" が必ず必要 コンテナを立ち上げる前に .env ファイルに .env.local ファイルの内容をコピーするコマンドを実行する Makefile up: touch .env cp .env.local .env .vendor/bin/sail up おわりに 便利機能や簡単ツールはそのメリットだけ制限や柔軟性の部分で惜しい部分があるなぁと感じましたね! 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravel/homesteadでシンボリックリンクを方法

はじめに laravel/homesteadでシンボリックリンクをはり、画像を表示させようとしたところなかなか苦戦したので皆さんの助けになればと思い記事にしました。 やりたいこと ユーザー登録の際にアイコン画像を登録し、表示させたい 環境 windows8 laravel homestead(vagrant + virtualbox) laravel 6 やり方 homestead環境下でシンボリックリンクを行うには普通ですとエラーになります。 解決方法としては管理者権限でコマンドプロンプトを開くことです。これでエラーにならずシンボリックリンクを実行することができます。vagrant内にアクセスし、 php artisan storage:link を実行します。 シンボリックリンクとは何かというと、laravelの画像の保存先はディフォルトでstorage/app/publicディレクトリ直下に保存されるのですが、外部からアクセスして画像を表示させるには一番上の階層のpublicディレクトリ直下に画像がある必要があります。そこでstorage/app/publicディレクトリへのショートカットを一番上の階層のpublicディレクトリ直下に作りアクセス可能にするものがシンボリックリンクです。シンボリックリンクを張ることで画像を表示させることが可能になります。 あとがき 初めてQiita投稿、またプログラミング初心者のためわかりずらいところもあるかもしれませんが、今後も投稿を続けたいと思います。頑張ります!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

①Vue.js & Laravel(環境構築)

【目標】LaravelにVue.jsを埋め込んだフォルダを作成し、SPAの土台を作る 前提①パソコンにnodeがインストールされている こちらのコマンドで確認しましょう $ node -v v14.16.1 もしインストールされていない場合はこちらからインストール 前提②パソコンにcomposerがインストールされている こちらのコマンドで確認しましょう $ composer --version Composer version 2.0.12 もしインストールされていない場合は(MAC) $ curl -sS https://getcomposer.org/installer | php $ sudo mv composer.phar /usr/local/bin/composer これでインストール完了です。 【手順】①フォルダの作成②データベースへの接続③Vue.jsとLaravelの接続 ①フォルダの作成 $ cd [フォルダを作りたい階層] (フォルダを作りたい階層に移動) $ composer create-project "laravel/laravel=7.*" hoge (「hoge」という名前でフォルダの作成) $ cd hoge (作成したフォルダの中に移動) $ composer require laravel/ui:2 (UIの様々な機能導入) $ php artisan ui vue (vue導入) $ php artisan ui vue --auth (ログイン機能導入) $ npm install --save vue-router (vueルーター導入) $ npm install (npm導入) それではサーバーを立ち上げて確認してみましょう! $ npm run watch (フォルダに変更がある度にビルド) $ php artisan serve (サーバーを立ち上げる) ターミナルを2枚開き上記のコマンドを実行してください。 上記の2つのコマンドは開発中常に実行させます。 表示されたURLにアクセスしウェルカム画面が表示されれば成功! これで「①フォルダの作成」は完了です! ②データベースへの接続 .env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=8889 DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD=root 上記の部分を自身のデータベースの環境に合わせ書き換えましょう $ php artisan migrate:refresh --seed こちらを実行しテーブルが作成されれば「②データベースへの接続」が完了です ③ルーティングを設定しvueのexampleコンポーネントを表示させる 不要ファイルの削除、必要ファイルの作成 下記のコマンドでフォルダを整理します $ rm resources/views/home.blade.php $ rm resources/views/welcome.blade.php $ rm app/Http/Controllers/HomeController.php $ rm resources/js/components/ExampleComponent.vue $ touch resources/views/app.blade.php $ touch resources/js/components/AppComponent.vue $ touch resources/js/components/Header.vue $ mkdir resources/js/components/task $ touch resources/js/components/task/Task.vue $ mkdir resources/js/components/user $ touch resources/js/components/user/User.vue resources/routes/web.php <?php use Illuminate\Support\Facades\Route; - /* - |-------------------------------------------------------------------------- - | Web Routes - |-------------------------------------------------------------------------- - | - | Here is where you can register web routes for your application. These - | routes are loaded by the RouteServiceProvider within a group which - | contains the "web" middleware group. Now create something great! - | - */ Route::get('/', function () { - return view('welcome'); + return view('app'); }); Auth::routes(); - Route::get('/home', 'HomeController@index')->name('home'); resouces/views/app.blade.php <!doctype html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravue') }}</title> <link href="{{ mix('/css/app.css') }}" rel="stylesheet"> </head> <body> <div id="app"> <app-component></app-component> </div> <script src="{{ mix('/js/app.js') }}" defer></script> </body> </html> resouces/js/components/App.vue <template> <div class="appComponent"> <Header /> <div class="container"> <router-view /> </div> </div> </template> <script> import Header from "./Header.vue"; export default { components: { Header, }, }; </script> resouces/js/components/Header.vue <template> <div class="header"> <div class="header_nav"> <router-link to="/task">task</router-link> <router-link to="/user">user</router-link> </div> </div> </template> <style scoped> .header { text-align: center; background-color: #000066; margin-bottom: 50px; } .header_nav { padding: 30px; } .header_nav a { color: white; text-decoration: none; font-size: 25px; margin-right: 25px; } .header_nav a:last-child { margin-right: 0; } .header_nav a.router-link-active { color: #f3920b !important; } </style> resouces/js/components/task/Task.vue <template> <div class="taskComponent"> タスク画面 </div> </template> <script> export default { data() { return { }; }, methods: { }, mounted() { }, }; </script> <style lang="scss" scoped> </style> resouces/js/components/search/Search.vue <template> <div class="searchComponent"> 検索画面 </div> </template> <script> export default { data() { return { }; }, methods: { }, mounted() { }, }; </script> <style lang="scss" scoped> </style> resouces/js/components/user/User.vue <template> <div class="taskComponent"> ユーザー画面 </div> </template> <script> export default { data() { return { }; }, methods: { }, mounted() { }, }; </script> <style lang="scss" scoped> </style> resouces/js/app.js - /** - * First we will load all of this project's JavaScript dependencies which - * includes Vue and other libraries. It is a great starting point when - * building robust, powerful web applications using Vue and Laravel. - */ + import VueRouter from 'vue-router'; require('./bootstrap'); window.Vue = require('vue'); - /** - * The following block of code may be used to automatically register your - * Vue components. It will recursively scan this directory for the Vue - * components and automatically register them with their "basename". - * - * Eg. ./components/ExampleComponent.vue -> <example-component></example-component> - */ - // const files = require.context('./', true, /\.vue$/i) - // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default)) - Vue.component('example-component', require('./components/ExampleComponent.vue').default); + Vue.component('app-component', require('./components/AppComponent.vue').default); + Vue.use(VueRouter); + const router = new VueRouter({ + routes: [ + { + path: '/task', + name: 'task', + component: () => import('./components/task/Task.vue'), + }, + { + path: '/search', + name: 'search', + component: () => import('./components/search/Search.vue'), + }, + { + path: '/user', + name: 'user', + component: () => import('./components/user/User.vue'), + }, + ] + }); - /** - * Next, we will create a fresh Vue application instance and attach it to - * the page. Then, you may begin adding components to this application - * or customize the JavaScript scaffolding to fit your unique needs. - */ const app = new Vue({ el: '#app', + router }); こちらの画面が表示されれば成功です 今回の目標「LaravelにVue.jsを埋め込んだフォルダを作成し、SPAの土台を作る」が達成されました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【CSS・SCSS】ファーストビュー表示速度改善|クリティカルCSSとは?使い方について

CSSの設計方法でクリティカルCSSに触れたので、考え方、目的、使い方をまとめてみた。 クリティカルCSSとは? ファーストビューに必要なCSSのみをページheadタグ中にstyleタグで埋め込み、それ以外のスタイルは</body>の上でlinkタグで読み込む。 styleタグで読み込む時はphpのfile_get_contentsメソッドを使う。 ▼目的 ページの読み込み速度改善のため。linkタグを使うとファイルの読み込みのため、クローラーがレンダリングをストップしてしまい描画が遅れる。 file_get_contentsとは? PHPのメソッドの一つ。・file_get_contents(URL)指定したURLの内容を読み込んで丸毎表示する。 htmlの中で使う時は以下のように記述する。 <style type="text/css"> <?= file_get_contents(CSSのURL)?> </style> <?= ?>は<?php echo ?>の省略形で指定した変数などを文字列として表示する。 実装手順 インラインで表示するファイルの準備 linkタグで読み込むファイルの準備 htmlファイルで読み込み 1. インラインで表示するファイルの準備 public > css > inview.css ファイル名はなんでもいいがhtml(ビュー)の中(in)に記述するということでinview.cssとしている。 2. linkタグで読み込むファイルの準備 public > css > overview.css ファイル名はなんでもいいがhtml(ビュー)全体のスタイルになるので、overviewとしている。 3. htmlファイルで読み込み .html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style type="text/css"> <?= file_get_contents( 'inview.cssへの絶対パス' ); ?> </style> </head> <body> <link href="overview.cssへの相対パス" rel="stylesheet"> </body> </html> Laravelでscssを使って実装する手順 応用編としてLaravelで実際に使う場合の例。 前提として、 - Larvel MixでWebpackを使ってコンパイルしているプロジェクト。 - cssの設計はFLOCSSを使用 (参考) ・Laravel Mixの使い方 ・FLOCSSとは? resources > sass 配下にファーストビューで使うcssのみをimportしたinview.scssを作成する。 resources > sass 配下にファーストビュー以外のcssをimportしたoverview.scssを作成する。 Laravel Mixでコンパイル対象のファイルを設定する。 resources > views > layouts の中に共通レイアウト用のビューを作成する。 1. ファーストビューで使うcssのみをimportしたinview.scssを作成する inview.scssの例 inview.scss @charset 'utf-8'; // foundation @import "foundation/variable"; @import "foundation/mixin"; @import "foundation/normalize"; @import "foundation/base"; // layout @import 'layout/grid/grid'; @import "layout/header"; @import "layout/container"; // object - component @import "object/component/breadcrumb"; @import "object/component/title"; @import "object/component/btn"; @import "object/component/link"; @import "object/component/pagenation"; @import "object/component/error"; // object - project // object - utility @import "object/utility/display"; @import "object/utility/space"; @import "object/utility/typography"; 2. ファーストビュー以外のcssをimportしたoverview.scssを作成する overview.scssの例。 overview.scss @charset 'utf-8'; // foundation @import "foundation/variable"; @import "foundation/mixin"; // layout @import "layout/footer"; ここでは、footerのレイアウトのみ読み込んでいる。 variableとmixinはコンパイルするときに必要になるファイル。 3. Laravel Mixでコンパイル対象のファイルを設定する resources/sass/*.scssにマッチするファイルを'public/css'配下に.cssとしてコンパイルするよう設定を記述する。 webpack.mix.js const mix = require('laravel-mix'); const glob = require('glob'); glob.sync('resources/sass/*.scss').map(function(file) { mix.sass(file, 'public/css') .options({ processCssUrls: false, postCss: [ require('autoprefixer')({ grid: true }) ] }) .version() }) ・autoprefixerとは? 必要なベンダプレフィックスを自動で付けてくれる便利なツール。 ・Laravel以外でLaravel Mixを使う場合はglob.sync~の上に以下を記述する。 mix.setPublicPath('./public') これがないとコンパイル後のファイルがpublic配下に生成されない。(コンパイルが途中で止まる) 4. 共通レイアウト用のビューを作成する ざっくり必要な物をまとめると以下のようになる。 meta情報。$metaという変数で渡す OGPの設定。FacebookやTwitterなどのSNSでの表示 Favicon と Apple Touch Iconの設定 ファーストビューのcssの読み込み。inview.css jsonld用のセクション header用のセクション 本文用のセクション footer用のセクション トップに戻るボタン ファーストビュー以外のcss読み込み。overview.css JavaScriptファイルの読み込み あとは必要に応じて、canonicalを設定したり、meta情報を変更するサービスや条件分岐を入れたり。 layouts>base.blade.php <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> <meta name="description" content="{{ $_meta['description'] }}"> <meta name="keywords" content="{{ $_meta['keywords'] }}"> <title>{{ $_meta['title'] }}</title> <!-- OGP --> <meta name="twitter:card" content="summary_large_image"> <meta property="og:site_name" content="{{ $_meta['site_name'] }}"> <meta property="og:title" content="{{ $_meta['title'] }}"> <meta property="og:description" content="{{ $_meta['og_description'] ?? '' }}"> <meta property="og:type" content="website"> <meta property="og:url" content="{{ url()->current() }}"> <meta property="og:locale" content="ja_JP"> @if (isset($_meta['og_image'])) <meta property="og:image" content="{{ $_meta['og_image'] ?? '' }}"> @endif <meta name="csrf-token" content="{{ csrf_token() }}"> {{-- Favicon & Apple Touch Icon--}} <link rel="icon shortcut" href="{{ asset("/img/favicon.ico") }}"> <meta name="apple-mobile-web-app-title" content="{{ $_meta['siteName'] }}"> <link rel="apple-touch-icon" href="{{ asset("/img/apple-touch-icon.png") }}"> <link rel="shortcut icon" href="{{ origin_url( asset("/img/favicon.ico") ) }}"> <link rel="manifest" href="{{ asset('/site.webmanifest') }}"> <meta name="msapplication-TileColor" content="#da532c"> <meta name="theme-color" content="#fff"> {{-- ファーストビューのcssの読み込み --}} <style type="text/css"> <?= file_get_contents(public_path('css/inview.css')); ?> </style> @yield('jsonld') </head> <body> @include('layouts.header') <main id="l-body" class="@yield('contentClass')"> @yield('content') </main> @include('layouts.footer') <div id="js-btn-to-top" class="c-btn-to-top"></div> {{-- ファーストビュー以外のcss読み込み --}} <link href="{{ asset('css/core_overview.css') }}" rel="stylesheet"> @yield('cssCode') {{-- JS --}} <script defer src="{{ asset('js/app.js') }}"></script> @yield('jsCodeBody') </body> </html> 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

実務経験に入ってから知ったLaravel/PHPの実装法まとめ

実務に入る前は知らなかったor使わなかった機能が多数用いられていた為、今後のために残していく。 一つ一つを細かに解説したものではなく、あくまでも「へーこんなのあるんだ」となるための、 まとめの記事ですのでお手柔らかに。 一貫性皆無かもしれない 間違い箇所あればガシガシ指摘お願いしますm(__)m 実務~現在まで まず実務に入ってから本記事投稿時点までで経験6ヶ月目です。 携わった(または現在も携わっている)プロジェクトにて Laravel/PHP/jQuery 自身が初めて参画した案件。 既にキックオフからは1年以上経過しており、中身のややこしさに幾度も絶望を味わう Laravel/LINEAPIでの独自API APIってすげー!!!ってなった。(語彙力) Smarty/PHP/VanilaJSでの保守・改修案件 「なるほど!わからん。」を体感 しかしおかげでほとんど知らなかった生のPHPの書き方とかもちょっと理解できた。 ※本記事は主に1つ目の案件で得た知見をまとめたものとなります。 参考までに 自身が実務に入る際は、Laravelを用いた簡単なCRUD開発ができる程度。 「SSHとSSLって何が違うん?」て聞かれて 「えーーーっとですね.....  最後がHかLかの違いです」となるレベル フロントは最低限書けるくらい。 CSSは大っ嫌いなのです 自作ヘルパー関数 Laravelには複数のグローバルなヘルパ関数が数多く存在しますが、 どこでも使える〇〇な関数あったらいいのになーと思ったとき簡単に作れてしまいます。 例:金額を引数に税込み価格を計算する関数 app/helper.phpを作成します。 (どのディレクトリでもいいです) helper.php <?php if (! function_exists('taxIncluded')) { function taxIncluded($price) { $tax = 10.0; return $price + floor($price * $tax / 100); } } せせ、先輩が作ったやつほとんどパクってる。 オートロードする autoload.filesを下記の様に編集します。 composer.json "autoload": { "files": [ "app/Http/helpers.php" ] }, オートロードとは? "https://laraweb.net/surrounding/1642/" 引用: PHPによるオートロード機能とはファイルを自動で読み込む仕組みのことです。 この機能を使うことでPHPファイルの冒頭に require を書きまくることはなくなりました。 オートロード機能を使用するには composer を使います。 composer を使用してライブラリをインストールするとvendor/autoload.phpというファイルが生成されます。 このファイルがオートロードの実体ファイルです。 このファイルを一度だけrequireすることで、vendor配下のライブラリをすべて自動的にロードしてくれます。 また、プロジェクトの直下にあるcomposer.jsonでオートロードするファイルを追加することもできます。 ↑いつもお世話になってます。 更新 $ composer dump-autoload あとは使いたいところで index.blade.php --略 <p>¥{{ number_format(taxIncluded($price)) }}(税込)</p> --略 どこでも使えます。 Eloquentモデルへのイベントをフックして何かする 例:Usersテーブルのemailが変更されたときメールを通知する モデルに$dispatchesEventsプロパティを定義する App\User.php use App\Events\UserUpdated; protected $dispatchesEvents = [ 'email' => UserUpdated::class ]; イベントクラスを作成する $ php artisan make:event UserUpdated 行いたい処理をイベントクラスに記述する App\Events\UserUpdated.php namespace App\Events; use App\Models\User; class UserUpdated { use Dispatchable, InteractsWithSockets, SerializesModels; public function __construct(User $user) {  /*メール送信処理を書く(詳しくはwebで)*/ } } こんな感じで簡単にフックできます。 ただ処理の中でEloquent\Model経由で何かしらすると再帰するので要注意とのこと。 いやー便利だけど難しい。 自作artisanコマンドを作る 画面作るまでも無いけど〇〇な処理ササッとできやんかなーというあなたに朗報です まずコマンド一覧確認 $ php artisan list ご親切なことに僕の嫌いな英語で各コマンドの説明がずらーっと 自作コマンド作成!! $ php artisan make:command SampleCommand app\Console\Command\SampleCommandが出来ました。 さて、ここになんやかんや書いていきます。 名前を変更 SampleCommand.php //ここを protected $signature = 'command:name'; //こうじゃ protected $signature = 'email:send {user_id}'; {}で引数の指定ができます。 また「:」をつけることで一覧でグルーピングして表示されます。 (無くでもOK) また、↑の場合は必須引数のため、引数抜きでコマンド実行すると怒られます 任意の引数の場合はこんな感じに。 SampleCommand.php protected $signature = 'email:send {user_id?}'; //指定されなかった場合のデフォルト値を指定 protected $signature = 'email:send {user_id=1}'; 引数に名前指定したり、オプションの指定もしたりできますが、 長くなるので詳しくはGoogle先生に尋ねてください。(投げやり) コマンドの説明 SampleCommand.php protected $description = 'メール送信する' 何をするコマンドか書いておきます。 引数取得 SampleCommand.php public function handle() { $userId = $this->argument("user_id"); $this->sendMail($userId); } あとは処理書いていけばokです 他にもオプション設定したり、なんやかんや色々できるので詳しくはググってください。 中断
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】function () use ($変数名)の意味。関数の外側で定義した変数を使う方法とエラーの対処法。

Laravelのルーティングでたみに見かけるfunction () use ($変数名)の意味について。 結論 関数の外で定義した変数を使う場合にuse宣言をしている。useで指定しないとエラーなる。 ▼実例 web.php $slug = 'test'; function() use ($slug) { Route::get('sitemap-{slug}.xml', 'SitemapController@test') ->name('test') ->where('slug', $slug); } URIがsitemap-test.xmlの時のみ、SitemapControllerのtestアクションを実行する。 ▼エラー useを使っていない場合 useを使わずに変数を使おうとするとエラーが発生する。 ErrorException (E_NOTICE) Undefined variable: regexs 実例2 正規表現を使ってリダイレクト設定する場合、ルーティング以外のロジック部分は冒頭にまとめて書くとわかりやすくなる。 web.php $removed_slugs = [ 'aaa', 'bbb', 'ccc' ]; $removed_slugs = implode( '|', $removed_slugs ); $regexs['removed_slugs'] = '(' . $removed_slugs . ')'; Route::get('test/{test_slug}', function() use ($regexs) { return redirect( route('test'), 301 ); })->where('test_slug', $regexs['removed_slugs'] ); }); test/の後に、aaa, bbb, cccが来た時のみルート名testに301転送をかける設定。 配列を正規表現の記述に変更するためにimplodeメソッドを使用。 ・implode( '繋ぐ文字列', 配列 ) 配列を指定した文字列で繋ぎ合わせて、一つの文字列に変換する。 【注意点】functionがネストしている場合 ミドルウェアを使う時などfunctionの中にfunctionがある場合など、深い階層にある場合は1階層ずつuse ($変数)で使いたい変数を渡していく必要がある。 web.php $slug = 'test'; Route::group(['middleware' => 'auth.very_basic'], function () use ($regexs) { Route::group(['prefix' => 'test', 'as' => 'test.'], function() use ($regexs) { Route::get('/{test_slug}', function() { return redirect( route('test'), 301 ); })->where('test_slug', $slug ); }); }); }); ミドルウェアのfunctionからその中のルーティングに変数を渡す時はuse ($変数)が必要。 接頭のURIとルート名を決めるprefixとasの中のfunctionでは渡さなくても機能する。(渡しても機能する) 深い階層の中にある場合は、fucntion毎にuse宣言をしておけば間違いない。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel 外部キーを設定 Cannot add foreign key

Laravel学習中に詰まったので記憶定着も兼ねてメモ。 症状 Authを使用したユーザー認証を導入し、usersテーブルがある。そこに、投稿用のpostsテーブルを用意。usersテーブルのPKであるidに対してpostsテーブルのuser_idに外部キーを設定する。 Users use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; #--省略-- public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } Posts public function up() { Schema::create('posts', function (Blueprint $table) { $table->engine = 'InnoDB'; $table->increments('id'); $table->integer('user_id'); $table->string('title'); $table->string('content'); $table->timestamps(); $table->foreign('user_id') ->references('id') ->on('users') ->onDelete('cascade'); }); } % php artisan migrate 結果 General error: 1215 Cannot add foreign key constraint (SQL: alter table `posts` add constraint `posts_user_id_foreign` foreign key (`user_id`) references `users` (`id`) on delete cascade) ---省略--- 677▕ catch (Exception $e) { ➜ 678▕ throw new QueryException( 679▕ $query, $this->prepareBindings($bindings), $e 680▕ ); 681▕ } 682▕ --- 調べてみた 外部キーが設定できないエラーなので、原因はUsersのidか、Postsの外部キーの設定のどちらかと考えるのが普通だと思う。一見外部キー制約の方には問題がなさそうだったため、まずはUsersのidから調べることにした。 そもそもid( )ってなんだ $table->id( )とあるが、このメソッドはなんだろうか。まあ、調べなくてもidを付与する的な何かということはわかる。ただ、その中で都合が悪いためにエラーが起きている可能性はある。 id( )はどこに定義してあるのか id( )は、\$tableに対して呼び出されている。$tableはBlueprintを引っ張っている。 Schema::create('posts', function (Blueprint $table){ Blueprintは、useで指定してあるIlluminate\Database\Schema\Blueprintにあるっぽいので、行ってみた。(ちなみに、Illuminateは、vernder/laravel/frameworkにある) あった。 public function id($column = 'id') { return $this->bigIncrements($column); } 超絶シンプル。しかし、これだとbigIncrementsが実行されていることしかわからない。 $thisって書いてあるので、ここからさらにbigIncrementsを探す。 public function bigIncrements($column) { return $this->unsignedBigInteger($column, true); } これもまたシンプル。だが、ここでもunsignedBigIntegerが実行されているだけ。 と、思いきや、よく考えると、unsignedじゃないか!! ということで、ここで型の不一致説が濃厚になる。 外部キー制約を設けたuser_idは、単純なinteger型。 id( )をinteger型にするのは現実的ではないので、user_idにunsignedを付与してみる。 Posts $table->integer('user_id')->unsigned(); % php artisan migrate:reset % php artisan migrate 一度実行しているので、リセットしてからマイグレート。(ただし、自分の場合はresetでpostsテーブルがドロップされない事件が起きていたので、mysqlから直接drop table postsで行った。) Migrating: 20xx_xx_xx_000000_create_users_table Migrated: 20xx_xx_xx_000000_create_users_table (27.76ms) Migrating: 20xx_xx_xx_100000_create_password_resets_table Migrated: 20xx_xx_xx_100000_create_password_resets_table (20.34ms) Migrating: 20xx_xx_xx_000000_create_failed_jobs_table Migrated: 20xx_xx_xx_000000_create_failed_jobs_table (19.75ms) Migrating: 20xx_xx_xx_084051_create_posts_table Migrated: 20xx_xx_xx_084051_create_posts_table (27.74ms) 成功した。 最終的には、idメソッドではなくincrementsメソッドを使用したが、同じくunsignedが付与される。 Users public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } Posts public function up() { Schema::create('posts', function (Blueprint $table) { $table->engine = 'InnoDB'; $table->increments('id'); $table->integer('user_id')->unsigned(); $table->string('title'); $table->string('content'); $table->timestamps(); // Set user ID to foreign key and automatic updating $table->foreign('user_id') ->references('id') ->on('users') ->onDelete('cascade'); }); } 以上。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

laravelで簡単なバッチ処理をしてみる

概要 業務でバッチ処理がちゃんと実施できているのか毎日定点観測をしているのだが、そもそもバッチ処理のコードを実際に書いたことがないので簡単なものでいいから実際に自分で作ってみようと思い作ってみることにした。 artisanでcommandクラスを作成する artisanで下記のコマンドを打つ コマンド一つで簡単にクラス作れるの便利ですね $ php artisan make:command Hogecommand 上記コマンド実施後にapp/Console/Commands配下に下記のクラスができていることが確認できると思います。 Hogecommand.php <?php namespace App\Console\Commands; use Illuminate\Console\Command; class Hogecommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'command:name'; /** * The console command description. * * @var string */ protected $description = 'Command description'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { // } } protected $signature = name artisanコマンドで実際に打つ時のコマンド名になる protected $description = バッチ処理の説明 public function handle()でバッチ処理の内容を記載する 既存のDBに山田太郎を登録させる それぞれ、$signature、$description、に下記の内容を書き、handle()内で処理を書いてみました。 Hogecommand.php <?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; use App\Models\Test; class Hogecommand extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'updateyamadataro'; /** * The console command description. * * @var string */ protected $description = 'テーブルに山田太郎を登録させる'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $item = new \App\Models\Test; $item->text = '山田太郎'; $item->save(); } } kernel.phpでコマンドを登録する $commandsの配列内にHogecommandクラスを記載します Kernel.php <?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ Commands\Hogecommand::class ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { // $schedule->command('inspire') // ->hourly(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } } artisanコマンドでupdateyamadataroを打つ php artisan updateyamadataro DBに登録されていることを確認する artisanコマンドでバッチを叩いて登録させただけの簡単な処理なので、応用的なこともできるように次回もっと工夫したのを作れるようにします 参考サイト Laravelのバッチ処理を作る
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む