Laravelでマスタデータ(key-valueデータ)をどう管理するか

Laravelで、フォームを作る時に、例えば選択ボックスがあって、そこから値を取り出したい場合があります。

例えば、性別[男、女]とか、都道府県[北海道〜沖縄]とか、カテゴリ[〜、〜]とか色々と考えられます。

それらのデータは、しょっちゅう変更があるもので、複雑なものであればデータベースにテーブルを作ってそこから引っ張ってくる方法もあるのですが、例えば男、女のような小さいデータセットであれば、わざわざそれをするほどでもないというか、いちいちテーブルを追加してデータをセットするというのが、Laravelの場合マイグレーションを通さないといけなかったりと色々と面倒です。

その場合に便利なやり方ですが、configに追加するのが楽です。

以下のページにやり方が書いてありました。

Laravelで都道府県のプルダウンメニューを作ってみる

一応手順についてメモしておきます

1.config以下に好きなファイル名で作成

都道府県であれば、per.phpのようなファイル名をconfig以下に作成して保存します。

return array(
  '1' => '北海道', 
  '2' => '青森県', 
省略
  '46' => '鹿児島県', 
  '47' => '沖縄県'
);

ちなみに、configのキャッシュが残っていると反映されないので、ファイルアップ後は以下のコマンドが実行必要です。

php artisan config:cache

上記の例では、pref.phpには一つしか配列が定義されていないですが、
複数定義したい場合は以下のように多次元配列でも設定が可能です。

return [
    "sex" => [
        "1" => "男",
        "2" => "女",
    ]
];

上記のように設定しても、後で問題なくアクセスできます。

コントローラーで取得→テンプレートに表示、または直接bladeに表示

作成したファイルは、config(ファイル名)で、いつでも参照して取得可能です。

コントローラーで取得してからテンプレートに表示する方法

public function sample() {
  $prefs = config('pref');
  return view('sample')->with(['prefs' => $prefs]);
}

直接テンプレートに記述する

以下のように直接取得することも可能です。

<select name="_pref">
  @foreach(config('pref') as $index => $name)
    <option value="{{ $index }}" @if(old('_pref') == $index) selected @endif>$name</option>
  @endforeach
</select>

多次元配列の場合は以下のようなかんじです。

例えば、config/common.phpに

return [
    "sex" => [
        "1" => "男",
        "2" => "女",
    ]
];

上記のような定義を例えばcommon.phpにした場合、以下のように記述できます。

<select name="sex">
    @foreach(config('common.sex') as $index => $value)
        <option value='{{ $index }}' @if(old('sex') == $index) selected @endif >{{ $value }}</option>
    @endforeach
</select>

 

Javascriptのクロージャについて解説

Javascriptのクロージャについての解説です。

Javascirptのクロージャとは何か

Javascriptのクロージャとは何か。

私の理解では

関数の中で関数を定義したもの

という理解です。
(あくまで私の理解です)

まず、基本的なところで

・ 関数を定義すると、関数内で定義した変数は関数外部から参照できない

という性質があります。
これはほとんどの人が知っていると思います。

例えば

function func() {
  var value = 1;
  console.log(value);
}
func(); // 1
console.log(value); // undefined

上記のようなプログラムの場合、関数を実行した場合、実行結果は
1になりますが、関数内の変数を出力した場合、
参照できていません。

function func() {
  var value = 1;

  function innerFunc() {
    value++;
  }
  innerFunc();
  console.log(value); // 2
}
func();

上記のようなプログラムの場合、関数の内部でinnerFuncという関数を定義して関数内で実行しています。
このinnerFUncをクロージャといいます。

innerFunc内では、外側の関数(エンクロージャ)で定義している
変数valueを呼び出していますが、その値を参照できているだけでなく、
更新することができます。

つまり、javascriptでは、関数の中で定義された関数の仕様は通常の
関数と、その外側の領域と違い、その関数内部で変数を参照したり、更新
したりできるのです。

このような仕組みを利用して、関数を定義する際に使用することがありますので、
性質として覚えておくと良いでしょう。

どのようなときに使うのか?

上記のクロージャの仕組みを使うと、関数内の変数の値を維持したまま、
その関数内の値を更新するプログラムをかけたりします。

例えば、関数内で定義した変数を、その関数内の関数を定義して返すような
関数にすることで、関数の外で変数を定義して更新したりしなくても、
関数を実行する度に関数を実行できたりするわけです。

書き方によってはクロージャを使わなくても実装できる場合もありますが、
コードがよりシンプルになったり、便利なケースがあるようです。
(未だにそういう場面に遭遇したことがないので分からない・・・)

JavascriptのSymbolについて解説

JavascrotのSymbol機能は、もともとJavascriptに存在していた機能ではありません。

ECMAScript6 (ES6, ES2015) で導入された機能です。

使い方

var a = Symbol();

このように使うことができます。

こうすることで、aには他の値を被らない値(具体的な数値ではない)が、自動生成されて代入されます。

例えば

var a = Symbol();
var b = Symbol();

上記のように定義しても、aとbの値は異なった値になります。

値の型はtypeofをすると「symbol」と表示される、独自の型となっています。

何のために存在しているのか

何故このような機能が追加されたのかというと、
自分でユニークな値を設定したつもりでも、他の値と予期しない形で衝突することが
あるため、そのような状況を防ぐためです。

PHPの無名関数(クロージャ)について

PHPの無名関数(クロージャ)についてのまとめです。

無名関数とは

無名関数とは、関数規則に沿って命名を必要とせず定義できる関数です。

function(引数) {
処理内容;
}

といった形で使用できます。

例えば

$func = function(引数) {
処理内容
}

といった形で定義した場合、この$funcは、ラムダ関数とも呼ばれます。

$a = $func(引数);

このような形式で、使用する場所で呼んで使用できます。

無名関数を使用するメリット

無名関数は概念的には関数と同じなので、無名関数にせず関数として定義して呼び出しても同じなのですが、
普通の関数を定義無名関数を使用することにより、その場限りで呼び出す処理の場合は、関数名を他の関数名と衝突しないで済む、プログラム全体が複雑にならないといったメリットがあります。

無名関数内の処理に外部の変数を使用したい場合

プログラムによっては、無名関数の中で使用するプログラムに、無名関数の外の変数を使用したい場合があります。

無名関数は関数なので、引数にしている変数以外の外部の変数は内部の処理には適用されません。

しかし、use文を使うことでその問題は解決できます。

$func = function(引数A) use(変数B) {
処理内容;
}

このように無名関数を使用することで、処理内容で引数Aだけでなく外部の変数Bも使用できます。

Laravelのbladeテンプレートで配列の要素の存在を判定する方法

Laravelのbladeテンプレートで、配列をforeachなどの構文でループで回すことはよくありますが、配列の要素が存在するかどうかをテンプレート上に記述したい場合があります。

その場合、以下のように記述できます。

@if(!$posts->isEmpty())

        

        @else

            

検索条件に合致する内容がありませんでした

@endif

上記の場合は、配列postsが空かどうかを判定し、空出ない場合はループ処理を記載しています。

配列にない場合はelse後の処理に記載しています。

ブラクラ中学生逮捕は何が問題なのかを分かりやすく解説

ブラクラサイトへのURLを掲示板サイトに書き込んだ罪で13歳中学生を含む3名が補導された事件を受けて、Twitterでも様々な議論がされました。

不正プログラム書き込み疑い補導 | NHKニュース

この事件について、自分も最初は何のことかよく分からなかったのですが、調べると警察の対応に問題があると感じたので、どういうことか分かりやすく解説してみます。

まず、問題となったのは、そもそも逮捕された人がそのサイトを作ったわけではないようなのですが、掲示板サイトにそのサイトURLを書き込んだということだけらしいのですが、そのサイトのソースコードが上記のようです。

このスクリプトがどのような動作をするかの解説

このスクリプトについてですが、サイトに埋め込んで実際に動作させてみると分かるのですが、ほとんど迷惑な動作をするものでありません。

単に指定されたメッセージが表示されて「OK」を押すことで次のメッセージが表示される。そこで「OK」を押すと、次のメッセージが表示されます。
これがずっと続くわけです。

一見すると確かに迷惑そうに見えますが、処理としては「メッセージが表示される」というだけのものです。

しかも、昔よくあったブラクラのように、無限に出てきてコンピュータがクラッシュするというものでもなく、「OK」を押さないと次のメッセージが表示されないので、コンピュータに対してクラッシュさせたり、フリーズさせたりといったこともありません。

つまり、「OK」を押さずにそのページを閉じると処理は終了するので、処理を終了するのも極めて簡単です。

つまり、実際に掲示板に書き込まれたURLを踏んでそのページに誘導されても、実害はほとんどないわけです。

昔あったようなブラクラは、そもそも今回の件はメッセージを表示するだけなのでブラクラにも該当しませんが、仮に今同様のブラクラのようなプログラムが実装されていても、最近のブラウザではそういった無限ループのプログラムには対応されていて実行されることはないようです。

つまり、逮捕した警察側に、そういった今回のプログラムがどういった動作をするかの知識が欠如しているために逮捕や家宅捜索にまでつながっているという見方ができます。

どう考えても、今回の件はウイルスに感染するでもなく、コンピュータがクラッシュするわけでもなく、これで逮捕されるのであれば、ちょっとしたジョークで逮捕されてしまうような事態になってしまうでしょう。

ブラクラ中学生逮捕事件に、javascriptの産みの親が降臨して言及

ブラクラサイトへのURLを掲示板サイトに書き込んだ罪で13歳中学生を含む3名が補導された事件を受けて、Twitterでも様々な議論がされました。

不正プログラム書き込み疑い補導 | NHKニュース

この件は、海外でも言及されて話題になっています。

そのやり取りが興味深かったので書いておきます。
(翻訳は微妙な部分を結構含んでるのですいません・・・)

まず、Googleで働いている日本人の方の投稿。

日本の警察は、たった数行のプログラムを実行するサイトへのリンクを投稿した人々を、「不正なプログラム」として逮捕しました。

信じられません。

これだと、多くのウェブサイトはFBIの統合任務部隊かなにかによって調査を受ける必要があるでしょう。
(冗談はおいておいて、日本の警察に、私はウェブブラウザ/セキュリティーについて解説を差し上げますので、ご連絡ください)

ここは、BrendanEich(Javascriptを作った人)の出番でしょう。

ここで本当にBrendanEichが降臨。

Netscape4ですら、Chromeの10年前にJSの無限ループの問題に対処していたよ。

Netscape2、3でも同じように対処するブランチコールバックがありましたが、しかし、それはいたって簡単です。

私達のJSであるNN4(SpiderMonkeyの最初にリリース!)ではそのスレッドで、knobchouck氏の功績により、1996年の秋にJSチームは2倍の規模に成長しました。

そうですねBrendan、私は知っています(泣)
広範な問題として、日本の警察は何に基づいて彼らを逮捕したのでしょうか…?
私は彼らの基準が何なのか理解できません。
昨年CoinhiveをWeb開発環境にインストールしたのも逮捕されました。
これは警告です。

ああ、CoinhiveからMoneoのマイニングですね、Moneroは法的処置としては有名ではありません。

日本の警察はMoneroが何かについての知識を持っていません。
彼らは逮捕した人々を「コンピュータへの訪問者を予期しないことに誘導していて、害を及ぼしている」としています。彼らのうちの何人かは政府とこの問題について法定で争っています。

わー。それが今年日本の日本ならば、専門家の助けが必要になるでしょうね。

彼らはコンピュータウイルスの法律に基づいて逮捕しているのかもしれませんが、無限ループとコインハイブの問題は別問題ですね。
それは注意が必要な傾向です。

Bootstrap4で、table-responsiveで横スクロールが出ないのに対処

Bootstrap4で、横長のtableにtable-responsiveクラスを適用して、はみ出させずに横スクロールさせようと思っていたのですが、何故かtable-responsiveを適用してもtableが横に飛び出したままで横スクロールが出現しませんでした。

書いていたコードは以下のような内容です。

-----

これで行けるはずなのですが・・・・

そしていろいろ試してみたのですが、原因がわかりました。

 ← 親要素のこれが原因
-----

原因としては、div class=”table-responsive”の親要素に、class=”row”が入っていました。

これを削除することで動作するようになりました。

修正後

 ← class="row"を削除
-----

TinyMCEを特定のtextareaに対して無効にする方法

TinyMCEを、特定のフォームに対して無効にする方法についての解説です。

TinyMCEは、簡単に入力欄にWYSIWYGを導入できるので便利ですが、
デフォルトの設定だと全てのtextareaにWYSIWYGが導入されてしまうため、WYSIWYGがついてほしくない
textareaはどうしたらいいのか分からず少し調べました。

TinyMCEのバージョンによって設定方法が異なると思うので、自分が使っているバージョン(4系)についてです。

TinyMCEを導入する際に、ヘッダの部分に以下のような記述があると思います。

tinymce.init({
            selector: "textarea",
            branding: false,

この箇所を、以下のように書き換えます

tinymce.init({
            selector: "textarea#mce",
            branding: false,

こうすることで、「textarea id=”mce”」となっているtextareaのみがTinyMCEの対象になります。

ちなみに、classでもいけます。

tinymce.init({
            selector: "textarea.mce",
            branding: false,

idだと、1つのテキストエリアしか対象にできないので、複数のテキストエリアを対象にしたい場合は、クラスで定義するのが有効です。

Laravelで「composer require doctrine/dbal」を実行でエラー「Installation failed, reverting ./composer.json to its original content.」の対処法

Laravelのマイグレーションで、カラム変更の機能を使う場合に、以下のエラーが発生しました

Changing columns for table “table” requires Doctrine DBAL; install “doctrine/dbal”.

テーブルのカラム変更をするにはdoctrine/dbalをインストールしろということ
公式サイトを確認したところ

composer require doctrine/dbal

をしないとエラーになるということで、実行。

すると、ここでもエラー

Installation failed, reverting ./composer.json to its original content.

インストールに失敗したので、composer.jsonを元に戻しましたということ。
もうちょっとエラーの内容を詳細に見てみます。

Your requirements could not be resolved to an installable set of packages.
あなたの要求は、インストール可能なパッケージのセットに対して解決できません

Problem 1
– The requested package laravel/framework (locked at v5.8.2, required as 5.7.*) is satisfiable by laravel/framework[v5.8.2] but these conflict with your requirements or minimum-stability.

要求されたパッケージはLaravel5.8.2系を必要としているので、あなたのLaravelのバージョンに対しては対応できません

ということ。

というわけで、Laravelnバージョンを5.8系にアップすることで解決できました。

まずは、composer.jsonを編集します。

“require”: {
“php”: “^7.1.3”,
“doctrine/dbal”: “^2.9”,
“fideloper/proxy”: “^4.0”,
//ここを変更
“laravel/framework”: “5.7.*”,→”laravel/framework”: “5.8.*”,
“laravel/tinker”: “^1.0”
},

ここが5.7系になっていたので、5.8系に変更します。

その後、composer update

これで、Laravelのバージョンが5.8系に変更され、その後

composer require doctrine/dbal

これで無事インストールできました。

Laravel5でフォームにWYSIWYGエディタを利用する

Laravel5のフォームを作っていて、textareaの入力欄にWYSIWYGエディタを導入してWordPressっぽくするというのを
試していたのですが、以下の記事を参考にして実装することができました。

Laravel5にWYSIWYGエディタを実装する方法 | Qiita

詳しくは上記の記事を参考にしていただければ簡単に実装できます。

手順としては、

1・TinyMCE をダウンロードして、サーバへアップロード

2・jbimages をダウンロードして、TinyMCEのpluginsフォルダへアップロード
(configファイルの画像の保存パスの変更と、該当フォルダに書き込み権限をつける必要あり)

3・実装するサイトのヘッダにjsファイルのincludeと、javascriptのコードを追記する

これだけで、至って簡単に実装することができました。

ただ、上記のQiitaの記事が若干古くなっていました。

この記事執筆時点(2019年3月)では、TinyMCEの最新バージョンが5系となっていたのですが、jbimagesは4系にしか対応していないので、TinyMCEの4系をサイトからダウンロードして使用する必要があります。(5系では動作しませんでしたが、将来的には対応しているかもしれません)

4系での設定方法は、以下のページに解説がありました。

JustBoil.me TinyMCE Images Plugin — A simple solution for uploading images in TinyMCE

Bootstrap4で、テーブルのtdの横幅を設定する方法

Bootstrap4で、テーブルのtdの横幅を設定する方法についての解説です。

Bootstrap3までは、テーブルのtdに、グリッドのクラスをつけることで横幅がグリッドシステムを使って設定できていたのですが、Bootstrap4からはできなくなったみたいです。

bootstrap3でできていた

これが、bootstrap4ではできなくなっているので、スタイルで横幅を指定する必要があるようです。

参考
How to set up fixed width for td? | strackoverflow

何故Bootstrap4でできなくなってしまったのか分かりませんが、直書きで指定するっていうのも嫌ですが、仕方ないですね。
もっとシンプルに書けるいい方法がないもんなのでしょうか。

Laravelの認証機能(auth)で新規ユーザ登録をできなくする

Laravelの認証機能で、ユーザ登録をできなくする方法についての解説です。

Laravelには、標準でAuth(認証機能)がついているので、標準で入っている認証機能を導入するのは非常に簡単です。

しかし、この標準のAuth機能は、Authをかけているページをログインページにリダイレクトし、そこでメールアドレスとパスワードを入力すればログインすることがでできるのですが、新規登録への導線がついているので、管理者だけログインできればよくて、それ以外のユーザの新規登録を受け付けていない場合があると思います。

そのような場合でも、routesの設定を変更することで簡単に対応することが可能です。

php artisan:make auth

をすることで、routesのweb.phpに以下の2行が追加されていると思います。

Auth::routes();

Route::get('/home', '[email protected]')->name('home');

これを、以下のように変更すればOKです。

//ここを変更
Auth::routes(['register' => false]);

Route::get('/home', '[email protected]')->name('home');

これをすることで、ログイン画面にRegisterと表示されている部分が消え、登録ができなくなる他、登録URLにアクセスしても404 not foundになります。

合わせてRegisterControllerを削除するように、Laravel公式サイトには書いてありますが、特にその対応をしなくても機能しなくなっていたので問題ありませんでしたが、一応削除しておくと良いと思います。

bootstrap4で、h1のフォントサイズを変更する方法

boostrrap4で、h1のフォントサイズを変更する方法についての解説です。

何故h1のフォントサイズ変更が必要か

boostrap4で、h1のフォントサイズがデフォルトでh1のままだと大きすぎると思っていました。

大きすぎる

これを調整する方法なのですが、クラス名のh1からh6を指定することで調整できるのです。

クラスでh6を指定してやるとだいぶ小さくできました。

大きすぎる

h1で指定されているけど大きさはh6の大きさ

クラスはh1からh6まで指定できるので、好みの大きさを指定すると良いです。

Google Analyticsで、ランディングページのページタイトルを見る方法

Google Analyticsで、ランディングページのページタイトルを見る方法についての解説です。

Google Analyticsで、ランディングページのページタイトルを見るには

Google Analyticsで、普通の全体のページビューでタイトルを見る方法は簡単で、

行動→サイトコンテンツ→すべてのページを見に行ったときに

プライマリディメンション:ページの右に「ページタイトル」というタブがあるので、そこをクリックするとページビューをページのタイトルごとに見ることができます。

これは非常に便利で、何故かと言うと、URLを見ても実際にどのページかというのはひと目でわからないので、タイトル名で表示してくれたほうが分かりやすいからです。

一方で、ランディングページ(ユーザがアクセスする際に入り口となったページ)をページタイトルで見ようとすると、、、
(ランディングページは、行動→サイトコンテンツ→ランディングページで見ることができます)

ページビューごとにあったタブメニューがないのです。

これは不便で、ランディングページでは、ページのタイトルでは見れないので、URLごとにサイトでいちいちチェックしないといけないと思っていたので不便でした。

しかし、解決策がありました。

セカンダリディメンションでタイトルを出せる

ランディングページの「セカンダリディメンション」を出して、検索項目を書くことができる欄に

「タイトル」

と入れて検索すると

「ページタイトル」

という項目があるので、そこをクリックすると、ページURLの隣に、ページURLに対応するページタイトルが表示されるようになります。

私の場合は、このことにずっと気が付きませんでしたので、分かってページ解析の際にとても助かりました。

確定申告時の控除について自分用まとめ

  • 2019年2月25日 7:14 PM
  • 雑記

毎年個人事業主として確定申告を行っているのですが、毎年どのような税金に対してどういった控除が適用されるのか忘れるのでメモとして書いておきます。

所得税

自分の場合は以下の計算です。

総売上から以下のものを引く

経費(変動)
所得税基礎控除(38万固定)
青色申告控除(65万)
生命保険控除(上限5万)
社会保険控除(国民年金)
社会保険控除(国民健康保険)

というわけで、まず青色申告をしているので、青色申告で65万、所得控除で38万、年金で大体20万、保険料も最低10万近くは払うので、何もしていなくても130万くらいは控除されるので、130万以上は年間収入がないと、所得税は発生しないことになります。

収入が少ない人には優しいですね。

また、使った経費も売上から引いたものが総所得になりますので、経費はまめにつけておく必要があります。

また、他から支払われた給料がある場合は、源泉徴収票を貰ってきちんと入力しておくと、源泉税を余計に払っている場合、あとで還付申請を行うことができます。

年間に通院してかかった医療費が10万円以上ある場合は、医療控除がこれに加えて発生します。

自治体に払っている住民税(市民・県民税)は控除対象にならないので、領収書の添付も不要です。

所得税の計算方法は累進課税制度なので、所得が多いほど税率も高くなる仕組みになっています。

市民県民税・住民税

市民税・住民税は、地区によって計算方法が異なるので、自分が所属している自治体の計算方法を調べる必要があります。

私の場合は以下の通りでした。

均等割 5000円

均等割は全員必ず払わないといけないので、無収入でも、その地区に住んでいる限り払わないといけません。

所得割

総売上から以下のものを引く

経費(変動)
青色申告控除(65万円)
基礎控除(33万円固定)
生命保険控除(上限3万5000円)
社会保険控除(国民年金)
社会保険控除(国民健康保険)

所得税と計算が似ていますが、基礎控除の金額、生命保険控除の金額が少し異なるのに注意が必要です。

所得税と同じく、青色申告と基礎控除で100万くらい、年金(20万)、保険料(10万)を加えるとやはり大体130万くらいはいくので、130万くらいは売上がない限りはこちらも所得割が発生しないので、均等割分だけの支払いが必要となります。

所得税・県民税は、所得から控除を引いたものに対して10%でした。

国民健康保険料

健康保険料も、住んでいる自治体によって計算方法が異なります。
私の住んでいる自治体では以下の通りでした。

賦課標準額の計算

総売上から以下のものを引く
経費(変動)
青色申告控除(65万円)
基礎控除(33万円固定)

医療給付費分

賦課標準額×8.58パーセント
均等割 27000円
平等割 20400円

後期高齢者支援金分保険料

賦課標準額×2.13パーセント
均等割 7,200円
平等割 4.800円

国民健康保険料は、所得税と市民・住民税と違い、生命保険、社会保険の控除がありません。
シンプルに売上-経費-青色申告控除-基礎控除となっています。

ただこれも、青色申告の場合、65万円の控除と基礎控除の33万円があるので、100万円以上は収入がない場合、確実に払わないといけない均等割、平等割のみが対象となります。

私の住んでいる自治体の場合は、均等割、平等割だけで 59,400円なので、最低でも年間6万円程度は国民健康保険に加入する限りは支払わないといけません。

計算方法と税率から比較して、ある程度の収入になるまでは健康保険料が一番多くなる仕組みになっています。

ただし、健康保険料には上限(77万円)があるので、収入が増えてくると、健康保険料より住民税・県民税や所得税のほうが多くなるような仕組みになっています。

mineo+iPhoneで「データ通信機能を起動できませんでした」の対処法

  • 2019年2月20日 8:16 PM
  • iPhone

iPhoneとmineoで、Wi-Fi-なしでインターネットに接続しようとすると「データ通信機能を起動できませんでした」と表示される問題の対応についての解説です。

問題について

iPhone7(SIMフリー)に、mineo(Dプラン)のSIMカードを入れて設定した後、Wi-Fiなしでインターネットに接続しようとすると「データ通信機能を起動できませんでした」と表示されてインターネットにつながらない。

iPhone+mineoで「データ通信機能を起動できませんでした」の対応

対処法

以下の2つの方法のいずれかで対応できると思います。

ネットワーク設定をリセットして再度接続

iPhoneの設定→一般→リセット→ネットワーク設定のリセット

で一旦ネットワーク設定をリセット

設定→一般→プロファイルで、入っているプロファイルを削除

自分が利用しているプランのmineoのプロファイルを再度インストール

ネットワーク設定(iOS端末)|各種設定|ご利用時の各種設定|初期設定と各種設定|mineoユーザーサポート

モバイル通信のデータ通信設定の見直し

設定→モバイル通信→通信のオプション→4Gをオンにする→データ通信のみに設定
(音声通話とデータになっている場合はデータ通信のみに変更)

私の場合は上記をすることで解決しました。

モバイル通信のデータ通信設定をデータ通信のみにすると電話ができなくなるのではないかと不安に思うかもしれませんが、関係ありません。
4Gでの「音声+データ通信」というのは、「VoLTE通信」なので、データ通信のみにしても、データ通信が4Gになるだけで、音声通話は3G帯域で行えるので問題ありません。あくまで4Gを音声通話で使うことで、音声がよりクリアになるというだけの話です。

ちなみに、私の場合は、最初はデータ通信のみにすることでネットにつながるようになるのですが、後で再度「音声+データ通信」にしてみたところ、問題なく設定することができました。

そのため、結局のところmineoDプランの場合音声+データ通信でもできたので、そこが原因だったのかどうかは確かではありません(調べると、iPhone7とmineoDプランはどちらもVoLTEに対応しているということでしたので動作はするはずです)が、私の場合そこをデータ通信のみに切り替えることでネットにつながるようになったので、最初のネットワーク設定のリセットとプロファイルの削除と再インストールを行っても駄目だった方は一度試してみる価値はあるかもしれません。

Macのfirst aidでフリーズする対処方法

Macのディスクユーティリティで、first aidという機能があります。

これは、Macのディスクのエラーチェックをしてエラーがある場合は修復をする機能です。

しかし、この機能を使用していると、Macが固まってしまう現象に遭遇します。

この対処法について書きたいと思います。

フリーズしたように見えるのは正常動作

実は、first aid実行時に、Macがフリーズした「ように見える」のは正常な動作です。

first aidのキャプチャ画像

実行時に上記のような説明文が表示されますが、説明文に

「First Aidにより、起動ボリュームが一時的にロックされます。実行中はアプリケーションが応答しなくなります。」

と書いてあります。

そのため、First Aidを実行中にはしばらく他のアプリケーションをクリックしても応答しなくなるため、フリーズしたように見えますが、そのまま放置しておくと、時間はかかりますが実行が終了すると、きちんと操作できるようになります。

数時間放っておいてもそのままフリーズしたような状態のままの場合、本当にMacに何かエラーが発生している可能性がありますが、大抵は数十分程度放置していると実行結果がきちんと返ってくるはずです。

Laravelのファイル、フォルダのパーミッション設定

Laravelのファイルとフォルダのパーミッション設定についてです。

下記の記事が参考になりました。

Laravelのパーミッションを適切に設定 | Qiita

ディレクトリに対して権限を変更
sudo find laravel-root-directory -type d -exec chmod 750 {} \;

ディレクトリは750なので、所有者は全部可能、グループは読み実行可能、その他はできない設定

ファイルに対して権限を変更
sudo find laravel-root-directory -type f -exec chmod 640 {} \;

ファイルは640なので、所有者は読み、上書き可能、グループは読みのみ可能、その他はできない設定

最後にストレージとキャッシュの権限を変更
sudo chmod -R 770 laravel-root-directory/storage/ laravel-root-directory/bootstrap/cache/

ストレージ、キャッシュフォルダは所有者、グループは全部可能。その他はできない設定。

webサーバーのApacheをインストールすると作成されるwww-dataをグループに追加する
sudo chown -R myusername:www-data laravel-root-directory

これは、上記はwww-dataグループになっていますが、自分の環境(CentOS、nginx)では、httpdのグループがwwwだったので、以下の設定で上手くいきました。

sudo chown -R myusername:www laravel-root-directory

グループ「www」がphpを自分の環境の場合実行しているので、phpファイルは読み出しのみの設定で問題ありませんでした。
phpファイルの実行権限は、所有者、グループとも読みのみで問題ないんですね。
実行権限が必要なのかなとイメージ的には思っていたのですが。

例えばPerlなんかはCGIで755にするのが一般的でしたが、755ってのは所有者は全部できて、グループユーザが読み、実行権限があるということですもんね・・・。

使っているPHPはPHP-fpmなので、モジュール版ではなくてCGI版なのですが、同じCGIでもPerlとPHP-FPMではパーミッションが違うと、これはややこしい話です・・・。

Laravelで、404エラー permission deneidに対処

LaravelをCentOS、nginx環境にインストールしたのですが、初期設定完了後にサイトへアクセスすると、404エラーが発生しました。

エラーログを確認すると

permisson denied

が発生

phpファイルへのアクセスが拒否されているようです。

該当のエラーが起きているファイルやディレクトリを

chmod 777 エラーが起きているファイル

にしています。

結果、そこから先のファイルがさらにエラー

プロジェクトフォルダとファイルを全て777にしたらいけるんでしょうけど、それはそれでセキュリティに不安が残ります。

そもそも、nginx環境のphpのサイトで、プロセスを実行しているユーザってどのユーザなのでしょうか。

ps コマンドでプロセスを監視してみます。

すると

httpd php-fpm

となっていたので、ユーザ「httpd」が実行しているようです。

ユーザ「http」が属しているグループはどこなのでしょうか。

groups httpd

httpd : www

ということで、httpdユーザは、グループ「www」に所属していました。

プロジェクトフォルダのオーナーをwwwに変更してみます。

chown -R ユーザ名:www プロジェクトフォルダ名

これで、該当のフォルダのオーナーのグループが「www」になりました。

これで、サイトにアクセスするとエラーが消えて無事にサイトが表示されました。

php -vで表示されるphpバージョンと、phpinfo()で表示されるバージョンが違う対処

サーバはkusanagiを利用しているのですが、

phpinfo();

で表示されるphpのバージョンは7系なのに、

サーバにログインして、コマンドラインで

php -v

で表示されるのは、5系というよくわからない事象に遭遇して困ってしまいました。

これで何故困るかというと、Composerをアップデートしたときに、以下のようなエラーが出たからです

このComposerのアップデートには、phpの7系が必要だよ

みたいなエラーです。

しかし、phpinfo()で確認すると使っているPHPのバージョンは7系で、サーバにログインしてコマンドラインで実行している
Composerは5系のPHPを見ているようだという謎です。

調べてみると、KusanagiのPHPは、Webサーバで実行しているのはPHP-fpmというCGI版のPHPで、コマンドラインで実行しているのは、apache経由でモジュール版のphp5系で実行しているとかとういったかんじの現象のようでした。

Kusanagiのサーバでは、rootでサーバにログインして

kuasanagi php7

を実行することでphp7の実行環境に切り替わるようですが、apacheのモジュール版はphp7になっていない??

というよく分からない感じです。

さらに調べると、Kusanagiではサーバにログインして

yum update

で、モジュール版もPHP7に切り替わるといったことが書いてあったので、試してみると、

yum updateでエラー

で、これはサーバのPythonのバージョンを3系に上げていたので、Python2系で書かれているyumがエラーを起こしている様子
これは、いろいろとぐぐることで対応方法が出てきたので、yumのソースで、Pythonのパスが書いてあるところを、
サーバに残っているPython2系へのパスに何箇所か変更します。

これで yum update が実行できました。

これで、満を持して

php -v

を実行。すると、またも

php 5.6〜〜〜

と。え、php7に変わってない・・・?

いったん諦めてから翌日サーバにログインして

php -v

をもう一度実行してみると

PHP 7.3.1 (cli)

と、無事アップデートしてました。

よく分からないですが、yum updateしてからサーバに反映されるのに
時間が必要だった?みたいで、apacheを再起動することで反映されたのか、
よく分かりませんが、何にせよ時間経過で反映されました。

よく分かりませんが、Composerで実行していたPHPは、モジュール版というよりも、CLI版
というPHPのようで、確かにphp -vをすると

PHP バージョン(cli)

と、cliを後についています。
ここのCLI版のバージョンが影響していたようですが、何にせよ今回のケースでは
yum update で無事解決したようです。

この後、

Composer update

を実行すると、無事エラーにならずアップデートを行うことができました。

su で「bash: /home/ホームディレクトリ名/.bashrc:」 許可がありませんと表示される対処法

CentOSで、suコマンド(ユーザの変更)を実行した際に、以下のエラーメッセージが表示されました。

実行しようとしたコマンド
su ユーザ名

表示結果
bash: /home/ユーザのホームディレクトリ/.bashrc: 許可がありません

原因と対処

いろいろと調べてみたところ、該当のユーザのホームディレクトリに、そのユーザのアクセス権限がなかったことが原因でした。
何かの作業中に、間違ってそのディレクトリのオーナー権限を変更していたが原因だったみたいです。

以下の対応で解決しました。

cd /home/

chown ユーザ名:ユーザ名 ./ユーザのホームディレクトリ

これは、該当のディレクトリのオーナーとグループをそのユーザにするということです。

この後に再度suコマンドで該当のユーザに変更したところ、問題なく実行できるようになりました。

Composerをrootユーザで実行してはいけない理由

Linux系のサーバにrootユーザでログインして、Composerを実行しようとすると、以下の警告メッセージが表示されます

Do not run Composer as root/super user! See https://getcomposer.org/root for details

https://getcomposer.org/root を見ろということなのでアクセスしてみると、説明がありました。

How do I install untrusted packages safely? Is it safe to run Composer as superuser or root?

どうやって信頼されてないパッケージを安全にインストールできますか?
Composerをスーパーユーザやルートユーザで安全に実行できますか?

Certain Composer commands, including exec, install, and update allow third party code to execute on your system. This is from its “plugins” and “scripts” features. Plugins and scripts have full access to the user account which runs Composer. For this reason, it is strongly advised to avoid running Composer as super-user/root.

Composerのコマンドには、実行、インストール、アップデートが含まれていて、システムに影響するコードを実行することをサードパーティに許可します。
これは、プラグインとスクリプトの特徴に由来しています。プラグインとスクリプトはComposerを実行するユーザアカウントに完全にアクセスします。
この理由により、Composerをrootユーザで実行しないことを強く推奨します。

You can disable plugins and scripts during package installation or updates with the following syntax so only Composer’s code, and no third party code, will execute:

あなたはプラグインとスクリプトを、パッケージをインストールかアップデート時に以下のコードを追加することで無効にすることができます。
サードパーティのコードは実行できなくなります。

composer install –no-plugins –no-scripts …
composer update –no-plugins –no-scripts …

The exec command will always run third party code as the user which runs composer.

In some cases, like in CI systems or such where you want to install untrusted dependencies, the safest way to do it is to run the above command.

execコマンドはサードパーティのコードをcomposerを実行するユーザと同じように実行します。

いくつかのケースで、CIシステムまたは信頼されていない依存関係をインストールするときに、最も安全なのは上記のようなコマンドで実行することです。

CentosでComposerがインストールされているかどうかの確認

ComposerはPHPのパッケージ管理ツールですが、Composerを使用する前に、まず環境にComposerがインストールされているかの確認が必要になります。

CentOSでの確認方法についてですが、導入が完了されている状況であれば、コマンドラインで

composer

と打てば、下記のようなコマンドが表示されます。
インストールされている場合は、現在の入っているComposerのバージョンも確認できます。

composerの初期画面

Composerのインストールは、公式サイトからインストーラーをダウンロードしてセットアップ後、作成されたcomposer.pharを、

/usr/local/bin/composer

へ移動させることで実行可能になるので、ここまでができていれば上記の様な画面が表示されます。

なければcomposerコマンドが実行できないはずです。

インストールの手順は以下の通りです。

php -r “copy(‘https://getcomposer.org/installer’, ‘composer-setup.php’);”

php composer-setup.php

php -r “unlink(‘composer-setup.php’);”

mv composer.phar /usr/local/bin/composer

Laravel5.7 Homesteadで2つ目のサイトを追加する

Laravel Homesteadで、2つ目のサイトを追加する手順についてです。

Homesteadに2つ目のサイトを追加する手順についてですが、メインマシンのHomesteadディレクトリにある、Homesteadディレクトリにサイト構成を追記します。

Homestead.yml

sites:
– map: homestead.test
to: /home/vagrant/code/project1/Laravel/public

– map: homestead.test2
to: /home/vagrant/code/project2/public

databases:
– homestead

– site2

サイトと、データベースに必要なデータを追加します。

その後、Vagrantを再起動します

vagrant reload –provision

メインマシンのhostsファイルに、2つ目のサイトの設定を追記します。

192.168.10.10 homestead.test2

これで、homestead.site2にアクセスすると、

no input file specified

となります。

2つ目のサイトにLaravelがインストールされていないためです。

メインマシンから

vagrant ssh

で仮想マシンにログインします。

Laravelをプロジェクトフォルダにインストールします。

cd /home/vagrant/code/
composer create-project –prefer-dist laravel/laravel project2

この後、

homestead.site2

にアクセスして、Laravelの初期サイトが表示されたら初期設定完了となります。

エラー「rmdir: failed to remove ‘./diectory’: Device or resource busy」の対処法

Ubuntuのサーバで、特定のディレクトリを削除しようとしたところ、エラーが発生して削除できませんでした。

実行しようとしたコマンド
rmdir ./directory

発生したエラー
rmdir: failed to remove ‘./diectory’: Device or resource busy

このエラーについて調べてみたのですが、削除しようとしたディレクトリが、マウントディレクトリになっているということで、削除できないようです。

以下の対処をすることで削除できるようになりました。

sudo umount ./directory

上記コマンド(ディレクトリのマウントを解除)実行後、

rmdir ./directory

これで問題なく削除できるようになりました。

Laravel5.7で認証機能を使う

Laravelで認証機能を使う方法についての解説です。

Laravelには認証に必要な機能が最初から準備されているので、必要であれば使用することができます。

ちなみに、普通にベーシック認証を行うのであれば、.htaccessを使えばいいのですが、ここで言っている認証とは、ユーザIDとPWを入力してログインし、ログインしていなければログインページに飛ばされるというやつです。

あまりカスタマイズしないのであれば簡単に実装できます。

artisanでauth機能を準備する

コマンドラインで、Laravelのプロジェクトフォルダに移動し、

php artisan make:auth

このコマンドを実行します。

これを準備することで、必要なファイルがLaravelディレクトリに生成されます。

rouesファイルに追記されている

routesのweb.phpに、さきほどのコマンドを実行することで、下の2行の記述が追加されています。

Auth::routes();

Route::get(‘/home’, ‘[email protected]’)->name(‘home’);

上記は、homeディレクトリにアクセスしたときに、ログイン画面が表示される記述です。

あとは、ルートファイルの認証をかけたいページに、以下の記述を追加することで、該当するページに認証がかかります。

Route::get(‘/admin’, ‘[email protected]’)->middleware(‘auth’);

基本認証

ログイン画面を通した認証でなく、基本認証をしたい場合も簡単に実装できます。

auth.basicミドルウェアを使用します。

Route::get(‘/admin’, ‘[email protected]’)->middleware(‘auth.basic’);

基本認証を使用した場合に求められるID/PWは、laravelでプロジェクトを作成後にmigrateで作成される、userテーブルに登録されているユーザemailとパスワードと同じになります。

Laravelの初期設定

Laravelをインストール後に、初期設定で変えておく場所についてのメモ書きです。

.envファイル

.envファイルは、Laravelをインストールにしたフォルダにあります。

ここに、プロジェクトが接続するデータベースに関する設定などの情報が保存してあるので、必要に応じて変更する必要があります。

.envファイルを変更した後に反映させるには、

php artisan config:clear

を実行する必要があります。

app.php

/config/ディレクトリにある「app.php」ファイルに、いくつか設定に関する項目があります。

timezoneの設定です。日本のサイトの場合は、Asia/Tokyoにしておくとよいでしょう。

‘timezone’ => ‘Asia/Tokyo’,

デフォルトでは、en になっていますが、これは英語ということなので、日本語に設定します。

‘locale’ => ‘ja’,

ただし、これだけでは英語のままでに保護になりません。

/resources/lang/en

このフォルダとその中のファイル群を

/resources/kang/en

にまるっとコピーします。

あとは、それ以下にエラーメッセージの文章が全部英語で書いてあるので、それを
地道に日本語に変更します。

全部変更すると大変なので、使っているぶんだけ変更することでも問題ないと思います。

以下に翻訳版が上がっていました。
5.1のだそうですが・・・。

Laravel 5.1 日本語バリデーションメッセージファイル

また、これだけでは attributeが英語で出力されるので

さきほどの validation.phpの

‘attributes’ => [],

このようにすることで、対応するattributeが日本語で出力されます。

‘attributes’ => [
‘title’ => ‘タイトル’,
‘body’ => ‘本文’,
]

フォームでエラー時に入力値を保持する方法(Laravel5.7)

Laravel5.7で、フォームを作っていてエラー発生時に入力のフォームの値を保持する方法についてです。

結論からいうと、bladeテンプレートに {{ old(‘項目名’) }} の値をもたせることで入力前の値を保持できます。

こんなかんじです。

 <table class="table table-striped">

            <tr>
                <td>タイトル</td>
                <td><input type="text" name="title" value="{{ old('title') }}" placeholder="タイトルが入ります" /></td>
            </tr>

            <tr>
                <td>本文</td>
                <td><textarea name="body">{{ old('body') }}</textarea></td>
            </tr>

これは、入力値のフォームなので、はじめは空欄なので、入力前の値だけ保持できていればいいですが、これが編集する場合だと

初期) 編集前の値を持っている
エラー時) 入力エラーの値を持っている

の2つの状態を持っている必要があります。

これは以下のように記述することで解決できます。

<table class="table table-striped">

            <tr>
                <td>タイトル</td>
                <td><input type="text" name="title" value="{{ old('title' , $post->title) }}" /></td>
            </tr>

            <tr>
                <td>本文</td>
                <td><textarea name="body">{{ old('body', $post->body) }}</textarea></td>
            </tr>

oldの2つ目にデフォルト値を持たせることができます。

Larabel(5.7)でフォームを作成する手順

Laravelで簡単なフォームを作るのは基礎中の基礎ですが、慣れないうちは何箇所かつまづいたので記録に残しておきます。

フォームの仕様

記事を投稿してデータベースに保存する

件名(タイトル)と本文を入力し、データベースへ保存する。

サイトへアクセスすることで保存された記事一覧と、

ただこれだけのシンプルな仕様。

まずは環境構築

環境構築にはhomesteadを利用しました。

手順はこちらの記事に書いているので割愛します。

Laravel Homestead導入時の悪戦苦闘メモ

最初にやったのは古いバージョン(Laravel4系)だったので、再度やりなおしてLaravel5系でやってみました。

Laravel HomesteadをPHP7で動作させる

環境構築に手間取りましたが、ようやく動作したのでフォームの制作

1.マイグレーションでデータベースを作成

まずは、Homesteadの環境にログイン後、Artisanコマンドでテーブルを作成します
今回は、記事を投稿するので、postsというテーブルを作成

php artisan make:migration create_posts_table –create=posts

public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->boolean('delete_flg')->default(0);
            $table->timestamps();
        });
    }

ファイルを作成した後、

php artisan migrate

でテーブルを作成します。

モデル作成

テーブルを作成後、テーブルに対応したモデルを作成します。

php artisan make:model Post

これで、

/App/Post.php

が作成されました。
これで、テーブルに対応したオブジェクトを呼び出すことができるようになります。

このモデルはあとで使います。

管理画面を作る

まずは、記事を投稿する管理画面を作ります。

まずは管理画面の処理に対応するコントローラーを作成します。

php artisan make:controller AdminEntryController

これで、/Http/Controllers/AdminEntryController.phpが作成されました。

このファイルには管理画面の処理に対応する記述を追加していきます。

この時点では雛形が作られただけで処理は何も入っていません。

ルーティングを記述する

/admin/entry にアクセスしたとき、管理画面の投稿画面を表示するようにします。

ルーティングを記述ファイルは、/routes/web.phpにあります。

これに以下を追記します。

Route::get(‘/admin/entry’, ‘[email protected]’);

これでは、url「/admin」にアクセスしたときに、コントローラAdminEntryControllerの「top」メソッドにアクセスするということです。

最初は、とりあえずテンプレートを単純に表示するだけにしてみます。

public function top()
    {
        return view('admin.entry');
    }

これは、このメソッドが実行されたときに

/resources/views/admin/index.blade.phpを表示するという処理です。

まだテンプレートを作成してないので、URLにアクセスしてもエラーになります。

テンプレートを作成します。

bladeテンプレートの作成

bladeテンプレートは、laravelで使われているテンプレートで固有の記法があります。

CMSやフレームワークを使ったことがある人であればテンプレートという説明を聞くと大体イメージがつかめると思いますが、基本的には同じです。

ただ、bladeテンプレートの特徴としては、親と子の継承というものが特徴です。

大体のサイトは、基本となる共通部分があって、後はコンテンツ部分やタイトルなど、一部異なる部分があります。

Laravelのbladeテンプレートでは、共通している部分をまず、親のテンプレートとして作成します。

あとは、それぞれのページは、親のテンプレートを継承することで、異なる部分だけ作成するというようなイメージです。

この特徴により、子のテンプレートは最小限の記述で、また必要なテンプレートも最小限ですみます。

これで、bladeテンプレートの作成が完了したら、/admin/へアクセスすると、エラーがなければサイトが表示されます。

フォームを作成する

とりあえず、作成したフォームの雛形のテンプレートは以下の通りです。

注意が必要な点としては、フォームは、デフォルトの設定では、クロスサイトリクエストフォージェリ対策に、@csrfをテンプレートに埋め込んで置く必要があります。
これを書いていないと投稿時にエラーになります。

@extends('admin.parent')

@section('title', '投稿管理(入力画面)')

@section('content')
    <form action="/admin/entry/" method="post" id="formid" enctype="multipart/form-data">

        @csrf

        <table class="table table-striped">

            <tr>
                <td>タイトル</td>
                <td><input type="text" name="title" value="" placeholder="タイトルが入ります" /></td>
            </tr>

            <tr>
                <td>本文</td>
                <td><textarea name="body"></textarea></td>
            </tr>

            <tr>
                <td colspan="2" class="text-center">
                    <input type="submit" name="submit22" value="登録" class="btn btn-primary">
                     <input type="hidden" name="action" value="ok">
                </td>

            </tr>

        </table>

    </form>
@endsection

これを、実行したときに登録する処理を追加する必要があります。

まずは、ルーティングに以下を追加します。

Route::post(‘/admin/entry’, ‘[email protected]’);

最初のルーティングは、getで書いてましたが、投稿の処理はpostで渡すことで処理を分岐できます。

postでURLにアクセスしたときには、同じコントローラーでも異なるメソッドを実行するようにしています。

上記の処理ではcompleteメソッドを実行します。

completeメソッドの定義

completeメソッドを以下のように定義しました。

    public function complete(Request $request)
    {
        $post = new Post();

        $post->title = $request->input('title');
        $post->body = $request->input('body');

        //セーブメソッドは、継承している親クラスのモデルオブジェクトに定義されている
        $post->save();

        return view('admin.complete');
    }

$post = new Post();

で、最初に作成したPostモデルのオブジェクトを呼び出しています。

この記述で行うには、ファイルの先頭に

use App\Post;

を追記しておく必要があります。

この追記がない場合

$post = new App\Post();

になります。

その変数にポストで投げられた値をリクエストから取得して、saveメソッドでデータベースへ保存します。

その後は、完了画面のテンプレートを表示します。

この処理はかなりシンプルですが、Laravel独特の記法なので、覚えておく必要があります。

エラーがなければ、これでフォームの保存が実行できます。

投稿のサイトへの表示

今度はサイトに表示する処理を書いてみます。

一覧画面と詳細画面に分けて作成します。

まずはルーティングに必要な処理を追加します。

//トップページで一覧表示
Route::get(‘/’, ‘[email protected]’);

//詳細ページの表示
Route::get(‘/post/{id}’, ‘[email protected]’);

この例では、ページの表示処理を、PostsControllerというクラスを作成して行います。

トップページに一覧を表示する(indexメソッドの実行)処理、詳細ページを表示する処理(detailメソッドの実行)に分けています。

PostControllerは、最初と同じく

php artisan make:controller PostController

で作成しておきます。

以下が、PostsControllerクラスに定義した、トップページと詳細ページの表示のメソッドです。

use App\Post;

class PostsController extends Controller
{
    //トップページを表示する
    public function index(Request $request) {

        $posts = Post::where('delete_flg' , '<>', '1')
            ->get();

        return view('index', compact('posts'));

    }


    //ブログ詳細記事を表示する
    public function detail(Request $request, $id) {

        $post = Post::find($id);

        return view('post', compact('post'));

    }
}

indexメソッドでは、削除フラグが1でなく記事を取得するような処理を行っています。

detailメソッドでは、URLから取得したユーザIDに該当する記事を取得して、テンプレートに表示しています。

bladeテンプレートはそれぞれ以下のように定義しています。

@extends('layout')

@section('title', "新着記事")

@section('content')

    <ul>

    @foreach ($posts as $post)
        <li><a href="/post/{{ $post->id }}">{{ $post->title }}({{ $post->created_at->format('Y年m月d日') }})</a></li>
    @endforeach

    </ul>

@endsection
@extends('layout')

@section('title', $post->title)

@section('content')

    <p class="text-right">{{ $post->created_at->format('Y年m月d日') }}</p>

    <div class="contents">
    {!! nl2br(e($post->body)) !!}
    </div>

@endsection

記事の編集、削除

最後に、管理画面から記事の編集と削除を行えるような処理を追加します。

今回のケースでは、ルートファイルにまず以下のような処理を追記しました。

Route::get('/admin/edit/{id}', '[email protected]');

Route::post('/admin/edit/{id}', '[email protected]');

Route::get('/admin/delete/{id}', '[email protected]');

編集画面は、同じURLでアクセスしますが、最初はgetでアクセスし、編集完了処理はpostでアクセスすることで実行するメソッドを分けています。

//記事を編集する
    public function edit(Request $request, $id) {

        $post = Post::find($id);

        return view('admin.edit', compact('post'));

    }

    //記事の修正を完了する
    public function store(Request $request , $id)
    {
        $post = Post::find($id);

        $post->title = $request->input('title');
        $post->body = $request->input('body');

        //セーブメソッドは、継承している親クラスのモデルオブジェクトに定義されている
        $post->save();

        return view('admin.complete');
    }

    //記事の削除を完了する
    public function delete(Request $request , $id)
    {
        $post = Post::find($id);

        $post->delete_flg = 1;

        //セーブメソッドは、継承している親クラスのモデルオブジェクトに定義されている
        $post->save();

        return view('admin.delete');
    }

削除処理は、delete処理を使うのではなく、一応データベースには残しておきたいので、delete_flgを1にするアップデート処理にしています。

管理画面のトップページのbledeテンプレートも、記事一覧を表示するように変更しておきました。

@extends('admin.parent')

@section('title', '投稿管理')

@section('content')
<div class="text-right">
    <input type="submit" name="submit" value="新規登録" class="btn btn-primary" onclick="location.href='/admin/entry/'" />
</div>

    <div class="content">

        <table>
            @foreach ($posts as $post)
                <tr><td><a href="/post/{{ $post->id }}">{{ $post->title }}</a></td><td><input type="submit" value="編集" onclick="location.href='/admin/edit/{{ $post->id }}'" ></td><td><input type="submit" value="削除" onclick="location.href='/admin/delete/{{ $post->id }}'" ></td></tr>
            @endforeach
        </table>

    </div>

@endsection

ヘルパーを使ってテンプレートの記述を簡素化する

上記の例では、テンプレートの記述がややごちゃごちゃしていますが、
ヘルパーを導入することで、テンプレートの記述をすっきりすることができます。

詳しくは、以下のサイトに解説があります。

初めてのLaravel 5.6 : (16) Formの作成 – ララ帳

composer require “laravelcollective/html”:”^5.7.0″

これでヘルパーが導入できるので、これで以下のように記述することができます。

@extends('layout')
 
@section('content')
    

Write a New Article


{!! Form::open() !!}
{!! Form::label('title', 'Title:') !!} {!! Form::text('title', null, ['class' => 'form-control']) !!}
{!! Form::label('body', 'Body:') !!} {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
{!! Form::label('published_at', 'Publish On:') !!} {!! Form::input('date', 'published_at', date('Y-m-d'), ['class' => 'form-control']) !!}
{!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}
{!! Form::close() !!} @endsection

ホーム

フィード

ページの上部に戻る