20201015のPHPに関する記事は11件です。

使っているLaravelを6.x→8.xへアップデートしたときのメモ

はじめに

当方のメインサイトはLaravelで作られているのですが、トップページに1行しか無い寂しいサイト。そろそろ本格的に作ろうということでしたが、結構色々ありまして…最初、laravel/uiをインストールしようとしたら、laravelのバージョンが古すぎて入れないというのがきっかけで、バージョンアップしようということにしました。

背景

当方のサイトは、開発環境としてローカルマシン上でDockerを使って構築、本番環境にGithub(プライベートリポジトリ)を介して適応しています。

取り急ぎバージョンアップ

取り急ぎ着手しなければとなったのはLaravelのバージョン。
調べてみると、6.17という結構古いものでした。

root@78e089450650:/var/www# php artisan --version
Laravel Framework 6.17.1

Composerのアップデート

しかも、Composereを使ってみると「バージョンが古すぎる!」というメッセージが出ていました。

composer_エラー.png
手始めに、Composerをアップデートします。

root@***:~# curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.10.15) successfully installed to: /root/composer.phar
Use it: php composer.phar

root@***:~# mv composer.phar /usr/local/bin/composer
root@***:~# composer --version
Composer version 1.10.15 2020-10-13 15:59:09

これで、Composerのアップデートが出来ました。

6.x -> 7.x へのバージョンアップ

基本的に、Qiitaの記事で書かれている内容で対応できました(サイトの中身がほとんど無いので変更点は少なかった模様)。

Laravel 6.x→7.xバージョンアップ

この記事を基にファイルを編集、composer update かけることで7.xにアップデートできます。

root@***:/var/www# composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 12 installs, 58 updates, 3 removals
  - Removing symfony/debug (v4.4.4)
  - Removing jakub-onderka/php-console-highlighter (v0.4)
  - Removing jakub-onderka/php-console-color (v0.2)
  :
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
49 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

root@***:/var/www# php artisan --version
Laravel Framework 7.28.4

念の為、npm install -> npm run dev しておいたほうがいいと思います。

7.x -> 8.x へのバージョンアップ

基本的に、以下のサイトで書かれている内容で対応できました(サイトの中身がほとんどなかったため、composer.json の依存性のみを設定すればOKでした)

root@***:/var/www# composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 6 installs, 23 updates, 1 removal
  - Removing phpunit/php-token-stream (3.1.1)
  - Installing graham-campbell/result-type (v1.0.1): Downloading (100%)
  - Updating vlucas/phpdotenv (v4.1.8 => v5.2.0): Downloading (100%)
  :
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
71 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

root@***:/var/www# php artisan --version
Laravel Framework 8.10.0

バージョンアップのコツ

対応を端折らずに、1バージョンずつ上げることをお勧めします(6.x -> 7.x -> 8.x)。

最後に

開発環境で動作を確認したら、Githubにソースをpush、本番環境でpullして composer update -> npm install -> npm run production すれば、両方の環境でバージョンを揃えられると思います。

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

javascriptのLocalStorage を使ってお気に入り機能を自作してみた ②実装編-基盤作り-

どうも7noteです。プラグインより多機能なお気に入り機能を作成。前回の続き

①準備編がまだの方はこちら

今回作るお気に入り機能の特徴

  • JSON形式にして配列のまま保存。呼び出す時もJSONから普通の配列に戻して使用
  • 重複登録ができないように処理する
  • wordpressと絡める場合はphpの知識も多少必要

今回のメインソース

メイン基盤となるプログラムを書いていきます。
完成予定図は以下の通り。

完成予定図.js
/*お気に入りに追加機能*/
function addfav(oid){

    var key = 'お気に入りID';                                   

    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);
    if(oidlist == null){
        oidary = new Array(oid);
        var setjson = JSON.stringify(oidary);
        localStorage.setItem(key, setjson);
    } else {
        if(oidlist.indexOf(oid) == -1){
            oidlist.push(oid);
            var setjson = JSON.stringify(oidlist);
            localStorage.setItem(key, setjson);
        }
    }
}

/*お気に入りから削除機能*/
function removefav(oid){

    var key = 'お気に入りID';

    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);
    if(oidlist != null){
        var checkitem = oidlist.indexOf(oid);
        if(checkitem != -1){
            oidlist.splice( checkitem, 1 );
            var setjson = JSON.stringify(oidlist);
            localStorage.setItem(key, setjson);
        }
    }
}

※このソースだけでは何も動きません。これは関数なのでどこかで実行させないと動かない!

それではさっそく解説しながら一から書いていきたいと思います。

1.とりあえずLocalStorageを使ってみる。

script.js
var key = 'お気に入りID';                 /* keyの名前を決める。日本語もOK。 */
var oidary = new Array("No:20");        /* 値を決める。あとで複数の値を保持する予定なので配列形式に。 */
var setjson = JSON.stringify(oidary);   /* JSON形式に変換 */
localStorage.setItem(key, setjson);     /* ローカルストレージにデータを格納 */

上のスクリプトを動かすと、ブラウザのローカルストレージにデータを格納できます。
このスクリプトの場合、以下のようなデータが保管されます。

キー → お気に入りID
値  → No:20

実際に格納されているデータを見るには以下の手順で確認できます。

→「F12キーで検証ツールを開く」
→「Applicationタブを選択」
→「Storage欄のLocal Storageをクリック」
→「【file://】をクリック」
→KeyとValueにそれぞれ値が格納されています

実際の画面がこちら↓
f12.png

このようにしてデータを格納することができます。

2.LocalStorageから値を取得

次に格納された値を取得する方法

script.js
var key = 'お気に入りID';                  /* 取得するキーを指定 */
var getjson = localStorage.getItem(key); /* ローカルストレージから値を取得 */
var oidlist = JSON.parse(getjson);       /* 取得したデータがJSON形式から元に戻す */

console.log(oidlist); /* デバッグ用 */

localStorage.getItem()で特定のキーの値を取得することができます。
JSON形式で保存しているので、元の形式に戻すために、JSON.parse()をします。

3.LocalStorageから値を削除

特定の値のみ削除するには、一度値を取得してjavascriptで配列から削除する必要があります。

script.js
  var key = 'お気に入りID';                   /* 取得するキーを指定 */
  var oid = 'No:25';                        /* 取得するキーを指定 */
  var getjson = localStorage.getItem(key);  /* ローカルストレージから値を取得 */
  var oidlist = JSON.parse(getjson);        /* 取得したデータがJSON形式から元に戻す */
  var checkitem = oidlist.indexOf(oid);     /* 削除する値の配列番号を確認 */
  if(oidlist.indexOf(oid) != -1){           /* 値が存在するか確認 */
    oidlist.splice( checkitem, 1 );         /* 指定の値を削除 */
    var setjson = JSON.stringify(oidlist);  /* JSON形式に変換 */
    localStorage.setItem(key, setjson);     /* ローカルストレージにデータを格納 */
  }

ローカルストレージには、値を削除するStorage.removeItem()がありますが、これは値をすべて削除してしまうため、お気に入り登録した他のものまで削除してしまいます。


Storage.removeItem()をつかってしまった例
「No:20とNo:33をお気に入りしてました。」
「No:20をお気に入りから削除しようとしました。」

理想

{お気に入りID: "No:20", "No:33"}
↓(削除後)
{お気に入りID: "No:33"}

現実

{お気に入りID: "No:20", "No:33"}
↓(削除後)
{お気に入りID: }


JSON形式で値を格納しているため、一部の値のみ削除するには一度取り出す必要があるのです。
上記のプログラムでは、本当にその値があるかどうかを確認してから消すようにしています。

4.LocalStorageに値を追加する時の処理を見直す

ローカルストレージの特徴として、1つのキーには1つの値しかいれることができません。
そのため、同じキーにデータを入れると上書きされてしまいます。

上の1.2.3.で書いたスクリプトを単純にそのまま使っても、No:20をすでにお気に入りしていたとして、No:33を新しくお気に入りに追加すると、元のNo:20が消えてしまいます。

そこで、値の一部を削除する時同様に、一度データを取得してから配列に値を追加するやり方でデータを格納する必要があります。

script.js
var key = 'お気に入りID';                  /* 取得するキーを指定 */
var oid = "No:33";                       /* 格納するキーを指定 */
var getjson = localStorage.getItem(key); /* ローカルストレージから値を取得 */
var oidlist = JSON.parse(getjson);       /* 取得したデータがJSON形式から元に戻す */
if(oidlist.indexOf(oid) == -1){          /* 重複していないか確認 */
  oidlist.push(oid);                     /* 配列に値を追加 */
  var setjson = JSON.stringify(oidlist); /* JSON形式に変換 */
  localStorage.setItem(key, setjson);    /* ローカルストレージにデータを格納 */
}

※ローカルストレージにお気に入りIDというキーが存在しないまま動かすと、値(配列)が取得できずにエラーになります。1.の手順を事前に行うなどしてキーを作成してください。
検証ツール上で手動で追加することもできます。(ダブルクリック or 右クリックからの[Add new])

これで基礎的な処理はすべて書くことができました。
では実運用レベルまで持っていきましょう。

次の章が最後になります!!

【続き】③実装編-基盤作り-

前回(①準備編)の記事はこちら

おそまつ!

~ Qiitaで毎日投稿中!! ~
【初心者向け】HTML・CSSのちょいテク詰め合わせ

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

[Codewars] Bit Counting

概要

Codewarsの問題 Bit Counting の回答の復習とベストプラクティスをまとめる個人メモです。

問題

Write a function that takes an integer as input, and returns the number of bits that are equal to one in the binary representation of that number. You can guarantee that input is non-negative.
Example: The binary representation of 1234 is 10011010010, so the function should return 5 in this case

10進数を2進数に変換後、1の数を返却する問題です。

回答

decbinは10進数を2進数に変換し、mb_substr_countは第二引数の文字列の数を返却する関数です。

function countBits($n) 
{
   $binaryCode = decbin($n);
   return mb_substr_count($binaryCode, "1");
}

ベストプラクティス

function countBits($n) 
{
  return substr_count(decbin($n), 1);
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel php アウトプット

__constructメソッド,authorizeResourceメソッド

__constructメソッド

PHPのクラスでは、__constructメソッドを定義すると、クラスのインスタンスが生成された時に初期処理として特に呼び出さなくても必ず実行されます。

authorizeResourceメソッド

authorizeResourceメソッドの第一引数には、モデルのクラス名を渡します。
(なお、第一引数に渡したArticle::classは'App/Article'という文字列を返すので、第一引数には直接'App/Article'を渡しても構いません)
第二引数には、そのモデルのIDがセットされる、ルーティングのパラメータ名を渡します。
スクリーンショット 2020-10-15 11.02.39.png

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

Moodle 3.9 マニュアル - コースの相対日付

原文

コースの相対日付

コース相対日付機能を使用すると、コースまたはアクティビティの日付を、コース内のユーザーの開始日を基準にして表示できます。

ユーザーのコース開始日は、コース開始日より前に登録されている場合を除き、登録開始日です。登録されている場合、ユーザーの開始日はコース開始日となります。

コースの相対的な日付は、すべてのアクティビティでまだ実装されていないため、「実験的な機能」です。 Moodle 3.8では、以下の領域でのみ実装されています。

課題アクティビティ-提出を許可する、期日、締め切り日は、コース内のユーザーの開始日に関連しています。
毎週のコース形式-各コースセクションの日付は、コース内のユーザーの開始日に関連しています。

アクセス制限クイズなどの他のアクティビティでは、コースの相対的な日付はまだ実装されていません。

コースの相対的な日付を使用する

コースの相対的な日付を使用するには、管理者は最初にサイト管理/開発/実験設定でサイトに対してそれを有効にする必要があります。

サイトでコース相対日付が有効になっている場合、新しいコースを追加するときに、相対日付モードを有効にすることを選択できます。

注:コース設定を保存した後、相対日付モードを変更することはできません。設定は灰色で表示されます。相対日付モードは、既存のコースでは有効にできません。

関連項目

MDL-66044

カテゴリコース

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

【PHP】フォロー機能実装

PHPについて学習内容を備忘録としてまとめます。
ユーザー間のフォロー機能を実装しましたので、作成方法を記載します。

anime1.gif
完成したものは上記のようにフォローボタンを押すと、
フォローした人フォロワーの情報がテーブルに渡されます。

テーブル構成

まずはフォローした人フォロワーの情報を扱うため、そのテーブルを作成します。
テーブルの構成は下記のようになっています。
image.png
relationがテーブル名、follow_idfollower_idがカラム名になっております。
名前はご自身でお好みでつけても問題ございません。

※動作画面にidカラムとdelete_flgカラムがありますが、こちらはなくても実装できます。

フォローボタン実装

フォローボタンを表示させます。
表示先のページはフォローするユーザーのページを指定しています。

$current_user = get_user($_GET['user_id']);
$profile_user = get_user($_GET['page_id']);

<form action="#" method="post">
          <input type="hidden" class="current_user_id" value="<?= $current_user['id'] ?>">
          <input type="hidden" name="follow_user_id" value="<?= $user_id ?>">
          <?php if (check_follow($current_user['id'],$user_id)): ?>
          <button class="follow_btn border_white btn following" type="button" name="follow">フォロー中</button>
          <?php else: ?>
          <button class="follow_btn border_white btn" type="button" name="follow">フォロー</button>
          <?php endif; ?>
</form>

まず、get_user()を使用してログイン中のユーザー情報ページ内のユーザー情報を取得しています。
get_user()は下記のような構成の関数になっており、引数にあるユーザーIDからユーザー情報を返します。

function get_user($user_id){
    try {
      $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
      $user='root';
      $password='';
      $dbh=new PDO($dsn,$user,$password);
      $sql = "SELECT id,name,password,profile,image
              FROM user
              WHERE id = :id AND delete_flg = 0 ";
      $stmt = $dbh->prepare($sql);
      $stmt->execute(array(':id' => $user_id));
      return $stmt->fetch();
    } catch (\Exception $e) {
      error_log('エラー発生:' . $e->getMessage());
      set_flash('error',ERR_MSG1);
    }
  }

戻りまして、

$current_user = get_user($_GET['user_id']);
$profile_user = get_user($_GET['page_id']);

$_GET['user_id']$_GET['page_id']に関してはパスからユーザーIDを取得しています。

http://localhost/user/user_disp.php?user_id=20&page_id=23

このようなパスになっていた場合は$_GET['user_id']20$_GET['page_id']23が渡されます。

function check_follow($follow_user,$follower_user){
  $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
  $user='root';
  $password='';
  $dbh=new PDO($dsn,$user,$password);
  $sql = "SELECT follow_id,follower_id
          FROM relation
          WHERE :follower_id = follower_id AND :follow_id = follow_id";
  $stmt = $dbh->prepare($sql);
  $stmt->execute(array(':follow_id' => $follow_user,
                       ':follower_id' => $follower_user));
  return  $stmt->fetch();
}

次にcheck_follow関数でユーザーがフォロー関係にあるか確認をしています。
引数に渡されたユーザーIDがrelartionテーブルでフォロー関係にあった場合はtrueを返し、フォロー関係にない場合はfalseを返します。

          <?php if (check_follow($current_user['id'],$user_id)): ?>
          <button class="follow_btn border_white btn following" type="button" name="follow">フォロー中</button>
          <?php else: ?>
          <button class="follow_btn border_white btn" type="button" name="follow">フォロー</button>
          <?php endif; ?>

フォローボタンを表示していたブラウザ画面に戻りまして、先ほどのcheck_follow関数でtrueが返ってきた場合はフォロー中falseが返ってきた場合はフォローがボタンに表示されます。

これでフォローボタンの実装が完了したので、今度はクリックした際のajax処理についてみていきます。

ajax処理_js

フォローボタンをクリックした時にデータベースを操作するajax処理について実装していきます。
jsファイルに下記ソースコードを入力していきます。

  $(document).on('click','.follow_btn',function(e){
    e.stopPropagation();
    var $this = $(this),
    current_user_id = $('.current_user_id').val();
    user_id = $this.prev().val();
    $.ajax({
        type: 'POST',
        url: '../ajax_follow_process.php',
        dataType: 'json',
        data: { current_user_id: current_user_id,
                user_id: user_id }
    }).done(function(data){
      location.reload();
    }).fail(function(){
      location.reload();
    });
  });

処理としては要素名が.follow_btnのフォローボタンがクリックされたときに、current_user_iduser_idを取得しajax_follow_process.phpに遷移しています。
細かく処理をみていきます。

  $(document).on('click','.follow_btn',function(e){
    e.stopPropagation();
    var $this = $(this),
    current_user_id = $('.current_user_id').val();
    user_id = $this.prev().val();

$(document).on('click','.follow_btn',function(e){でフォローボタンがクリックされた際に処理が走るように定義されております。
そしてcurrent_user_id = $('.current_user_id').val();user_id = $this.prev().val();でブラウザからユーザー情報を取得しています。

<input type="hidden" class="current_user_id" value="<?= $current_user['id'] ?>">
<input type="hidden" name="follow_user_id" value="<?= $user_id ?>">

こちらは先ほどフォローボタンを表示していたブラウザ画面なのですが、$('.current_user_id').val();<?= $current_user['id'] ?>user_id = $this.prev().val();<?= $user_id ?>をそれぞれ取得しています。

    $.ajax({
        type: 'POST',
        url: '../ajax_follow_process.php',
        dataType: 'json',
        data: { current_user_id: current_user_id,
                user_id: user_id }

フォローボタンがクリックされたときにこちらの処理が走り取得したユーザー情報をajax_follow_process.phpに渡し遷移します。

    }).done(function(data){
      location.reload();
    }).fail(function(){
      location.reload();
    });

こちらではajax処理が成功した場合と、失敗した場合で処理が分岐しています。
今回の場合だとどちらもlocation.reload();なのでページをリロードして終わりです。
それでは遷移したajax_follow_process.phpでの処理をみていきます。

ajax処理_PHP

ajax_follow_process.php
  $user_id = $_POST['user_id'];
  $current_user_id = $_POST['current_user_id'];

    if(check_follow($current_user_id,$user_id)){
      $action = '解除';
      $flash_type = 'error';
      $sql ="DELETE
              FROM relation
              WHERE :follow_id = follow_id AND :follower_id = follower_id";
    }else{
      $action = '登録';
      $flash_type = 'sucsess';
      $sql ="INSERT INTO relation(follow_id,follower_id)
              VALUES(:follow_id,:follower_id)";
    }
    try {
      $dsn='mysql:dbname=shop;host=localhost;charset=utf8';
      $user='root';
      $password='';
      $dbh=new PDO($dsn,$user,$password);
      $stmt = $dbh->prepare($sql);
      $stmt->execute(array(':follow_id' => $current_user_id , ':follower_id' => $user_id));
      $return = array('action' => $action,
      'follow_count' => current(get_user_count('follow',$current_user_id)),
      'follower_count' => current(get_user_count('follower',$current_user_id)));
      echo json_encode($return);       
    }    
    catch (\Exception $e) {
      error_log('エラー発生:' . $e->getMessage());
      set_flash('error',ERR_MSG1);
      echo json_encode("error");
    }

jsファイルから取得したユーザー情報からフォロー関係にあるか確認し、返ってきた真偽値によってrelationテーブルを操作して処理を行っています。

これでフォロー機能が実装できたと思います。
先ほどの動作画面のようにフォローボタンをクリックしたときにrelationテーブルが操作される処理がされるはずです。

参考URL

https://github.com/nyann123/snspoi

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

Moodle 3.9 マニュアル - ステルスアクティビティ

原文

ステルスアクティビティ

Moodleの以前のバージョンには、アクティビティ(またはリソース)を「余分な」週またはトピック内に隠すことができる「癖」がありましたが、それでも学生はアクセスできます。これらは「孤立した」活動として知られており、Moodleユーザーはコースの特定のデザインを達成することができました。

Moodle 3.3以降では、任意のアクティビティまたはリソースを「ステルスモード」にして、より公式にサポートされている方法でこれと同じ効果を実現できます。

video

Moodle3.3でのステルス活動

ステルス活動を可能にする

管理者は、「高度な機能」から、コースで「ステルスアクティビティを許可する」ことができます。その後、教師はアクティビティ(またはリソース)を生徒が利用できるようにすることができますが、コースページには表示されません。この機能は、「週」、「トピック」、「ソーシャル」形式およびフロントページでサポートされています。他のコース形式では、実装されている場合とされていない場合があります。

ステルス活動の仕組み:例

教師は、いくつかのクイズを含むコースを持っています。 (以下の1)コースページがかなり長くなります。彼女は、コースをすっきりさせるために、クイズへのリンクを1ページ(以下の2つ)に追加することを好みますが、クイズを非表示にすると、学生はクイズにアクセスできなくなります。

Stealthexample1.png
Stealthexample1.png

彼女は編集をオンにし、[編集]メニューから各クイズを非表示にします。アクティビティが非表示になっていることを教師に通知する青いアラートメッセージに注意してください。

Stealthexample2.png
Stealthexample2.png

次に、[編集]メニューに戻り、[使用可能にする]オプションを選択します。青いアラートメッセージが変更され、アクティビティが利用可能であることを通知しますが、学生にはコースページに表示されないことに注意してください。

Stealthexample3.png
Stealthexample3.png

その後、彼女は1つのページでそれらのクイズへのリンクを作成できるようになり、生徒はクイズを表示して実行し、成績表で結果を表示できるようになります。学生にはクイズのリストは表示されません。

Stealthexample4.png
Stealthexample4.png

注:アクティビティは利用可能になる場合がありますが、「孤立したアクティビティ」の場合のように、下部のセクションだけでなく、どのトピックセクションにも表示されません。

管理者設定が無効になっている場合はどうなりますか?

「ステルスアクティビティを許可する」は高度な機能です。管理者が設定を有効にしていない場合でも、アクティビティを利用可能にすることはできますが、コースページには表示されません。

「ステルスアクティビティを許可する」が無効になっている場合にアクティビティ(またはリソース)を利用可能にするが、コースページには表示されないようにするには:

1.(たとえば)クイズを含むトピック全体を非表示にします。 (以下の1)。
2. [編集]メニュー(以下の2)から個々のアクティビティを利用できるようにします。
3. クイズのリンクを含む単一のページが、学生に表示されるトピックに含まれていることを確認してください(以下の3つ)。

Steallth5.png
Steallth5.png

カテゴリーコース

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

Cannot end a section without first starting one.エラー

【概要】

1.結論

2.Cannot end a section without first starting one.とは何か

3.どのように解決するのか

4.開発環境

1.結論

{{--   --}} でコメントアウトする。

2.Cannot end a section without first starting one.とは何か

Google翻訳すると、"最初にセクションを開始せずにセクションを終了することはできません"という意味になります。

3.どのように解決するのか

resorces/views/hoge/index.blade.php
  @section('content') #---❶
      @foreach($data as $item)
      <tr>
        <th>{{$item['name']}}</th>
        <td>{{$item['mail']}}</td>
      </tr>
      @endforeach
    </table>
  @endsection #---❶

  <!--{{-- <p>必要な時だけ記述できます</p> #---❷(1)

   @include('components.message' , ['msg_title'=>'OK'])
        @slot('msg_title')
          タイトル
        @endslot

  @endsection --}}--> #---❷(2)


❶で@section @endsectionをコーディングしていました。そして❷の部分は"command + /"でコメントアウトしていました。しかし、Vscode上のblade.phpでは<!-- -->緑色でコメントアウトになるものの❷(2)がコメントアウト されてないためか、"Cannot end a section without first starting one."というエラーが起きてしまいます。@endsectionが適用されてないことになってしまいました。{!-- --}}だけ囲っても色がついたコメントアウトにならないので<-- {-- --} -->というコーディングにしました。


4.開発環境

Mac catalina 10.15.4
Vscode
PHP 7.4.10
Laravel 8.9.0
Apache 2.4.41

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

Laravelの設定とファイルについて

Laravelプロジェクトを作成。

#laravelのバージョンは今回5.7でインストール。
$ composer create-project laravel/laravel=6.0 laravel_project

※バージョンを設定してインストールしないと最新版が自動的にインストールされます。

今回はエディタはvsCodeを使用。

タイムゾーンと言語設定

スクリーンショット 2020-10-11 0.09.26.png

#configのapp.phpの上から70行目を以下に変更する事で日本の時間に設定できる。

'timezone' => 'UTC',
            ↓
'timezone' => 'Asia/Tokyo',

#configのapp.phpの上から83行目を以下に変更する事で日本語に設定変更できる。

'locale' => 'en',
      ↓
'locale' => 'ja',

DBの文字コード変更

#configのdatabase.phpの文字コードを変更。

'charset' => 'utf8mb4',
          ↓
'charset' => 'utf8',

デバックバーのインストール

$ composer require barryvdh/laravel-debugbar

以下のようにデバックバーが表示される。Viewsで表示されているファイルの情報、Queriesでデータベースとのやりとりなどが確認できる。
スクリーンショット 2020-10-11 0.26.59.png

もしデバックバーを非表示にしたい場合は、envファイルを以下のように設定

#envファイルの上から4行めをfalseにする事で非表示にできる。
APP_DEBUG=false

それでも画面に残っている場合は、以下を実行する。

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

データベース設定

.envファイルの以下の部分になる。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=データベースの名前
DB_USERNAME=root
DB_PASSWORD=

データベース接続確認

今回はSequel Proを使用。Sequel Proにデータベース名を追加。

#以下のコマンドを実行
$ php artisan migrate

#テーブルが作成されます。

ルートについて

#routesのweb.phpファイル

Route::get('/', function () {
    return view('welcome);
});
//アクセスするとwelcome.blade.phpを表示する。


#resourcesのviewsフォルダの中にビューファイルを保存していく。

Laravel Artisanコマンド(Laravel 専用のコマンド)

#artisanが持っているコマンドの一覧を表示できる。
$ php artisan list

#サーバの機能を立ち上げる
$ php artisan serve

モデルについて

DBとのやりとりをPHPで書く事ができる。

モデルファイルの作り方

モデルの場合は単数形(例:Test)

#例1 appフォルダにTest.phpファイルができる。
$ php artisan make:model Test 

#例2 appフォルダにModelsフォルダができて、Test.phpファイルが中に入る
$ php artisan make:model Models/Test 

#例3 マイグレーションファイルとコントローラーファイルをまとめて作る場合

マイグレーションについて

DBのテーブルの履歴を管理する仕組み。
マイグレーションの場合は複数形で作る(例:Tests)

#以下のようなコマンドでマイグレーションファイルを作成できる。databaseフォルダの中のmigrationsフォルダの中に作成される。
$ php artisan make:migration create_tests_table 

#マイグレーションファイルを実行
$ php artisan migrate

tinker(DB簡易接続)

tinkerとはRailsで言うrails cのようなものでデータを簡単に追加したりできる。

例:
$ php artisan tinker

>>> $test=new App\Modesl\Test;
=> App\Models\Test{#3034}
>>> $test->text="aaa";
=> "aaa"
>>> $test->save();
=> true
//Testに入っている全てのデータを確認できる。データベースでも確認できる。
>>> App\Models|Test::all()

コントローラーについて

#以下のコマンドでコントローラーを作成できる。
$ php artisan make:controller TestController

ファイルの場所はappフォルダのHttpフォルダの中にControllersと言うフォルダがあり、その中に作成される。

web.phpに記載する場合

<?php

/*
|--------------------------------------------------------------------------
| 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');
// });

/*tests/testにアクセスしたらTestControllerに飛ばしてねと言うことになる。*/

Route::get('tests/test','TestController@index');

TestController.phpに記載する場合

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{

public function index(){
  return view('tests.test');
}    
}

resources/views/tests/test.blade.phpに記載

//これでアクセスするとtestと表示される。
test

DBから値を持ってきて中身を表示させる方法

TestController.phpを編集

<?php

namespace App\Http\Controllers;

//リクエスト処理に関して依存性の注入(DI)を利用
use Illuminate\Http\Request;

//モデルのデータを持ってくるために記載
use App\Models\Test;

class TestController extends Controller
{

public function index(){

//一旦変数に渡す
$values=Test::all();

//ddは処理を止めて変数の中身を表示できる。
//dd($values);

//valuesと言う変数をビューファイルに持っていくためにcompact関数を使用。
  return view('tests.test',compact('values'));
}    
}

test.blade.phpに記載

test

//コレクション型を表示させるためには@foreach(配列の要素がある分だけ繰り返し処理する)を使う.DBに入っている一覧が表示できる。

@foreach($values as $value)
{{$value->id}}<br>
{{$value->text}}<br>

@endforeach

ヘルパ関数とは

Laravelが用意してくれている便利な関数のことである。

例:route、auth(認証)、app、bcrypt(パスワードの暗号化)、collect、dd(処理を止めて変数の中身を表示)、env、factory、old、viewなど

以下参照
https://readouble.com/laravel/5.5/ja/helpers.html

コレクション型とは

配列を拡張した型(Laravel独自の型)。データベースからデータを取得したときはコレクション型になっている。

//ddでcollectionをみれる。
dd($values);

今回は試しにchunkで実行する。

<?php

namespace App\Http\Controllers;

//リクエスト処理に関して依存性の注入(DI)を利用
use Illuminate\Http\Request;

//モデルのデータを持ってくるために記載
use App\Models\Test;

class TestController extends Controller
{

public function index(){

//一旦変数に渡す
$values=Test::all();

//collectと言うヘルパ関数を作る。
$collection = collect([1, 2, 3, 4, 5, 6, 7]);

//chunkでグループ分けをする
$chunks = $collection->chunk(4);

//配列に変えている。
$chunks->toArray();

//ddは処理を止めて変数の中身を表示できる。
//dd($chunks);

//valuesと言う変数をビューファイルに持っていくためにcompact関数を使用。
  return view('tests.test',compact('values'));
}    
}

クエリビルダとは

SQL文で書く所をPHPの構文で記載したもの。
SQLインジェクションから守るために常にセキュアな状態になっている。

※ただデータを取得するだけならコレクションでも良いが、条件が細かくなってくるとクエリビルダの方がよりSQLに近い形で書ける。

クエリを書くにはDBファサードのtableを使う。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

//名前空間でDBファサードがインポートできたことになる。
use Illuminate\Support\Facades\DB;

use App\Models\Test;

class TestController extends Controller
{

public function index(){

$values=Test::all();

//データを取得(以下のようにselectで指定するとIDのみを取得する)
$tests = DB::table('tests')
->select('id')
->get();

dd($tests);

  return view('tests.test',compact('values'));
}    
}

※注意

#以下のようなrawを使用した文だとSQLインジェクションの脆弱性に注意する必要がある。ユーザーから入力があるものは特に注意。

$users = DB::table('users')
                     ->select(DB::raw('count(*) as user_count, status'))
                     ->where('status', '<>', 1)
                     ->groupBy('status')
                     ->get();

ファサード

アクセスする箇所を1つにしてそこにアクセスしたら中に色んなシステムがあるが、使う側としてはその入口だけ知っていればOKと言うような形の作り方。

Authやbladeなどがある。
https://readouble.com/laravel/6.x/ja/facades.html

ファサードの設定はconfigフォルダのapp.phpファイル内に記載ある。

191行目に定義されているものがファサードとして使えるものになる。

 'aliases' => [

        'App' => Illuminate\Support\Facades\App::class,
        'Arr' => Illuminate\Support\Arr::class,
        'Artisan' => Illuminate\Support\Facades\Artisan::class,
        'Auth' => Illuminate\Support\Facades\Auth::class,
        'Blade' => Illuminate\Support\Facades\Blade::class,
        'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
        'Bus' => Illuminate\Support\Facades\Bus::class,
        'Cache' => Illuminate\Support\Facades\Cache::class,
        'Config' => Illuminate\Support\Facades\Config::class,
        'Cookie' => Illuminate\Support\Facades\Cookie::class,
        'Crypt' => Illuminate\Support\Facades\Crypt::class,
        'DB' => Illuminate\Support\Facades\DB::class,
        'Eloquent' => Illuminate\Database\Eloquent\Model::class,
        'Event' => Illuminate\Support\Facades\Event::class,
        'File' => Illuminate\Support\Facades\File::class,
        'Gate' => Illuminate\Support\Facades\Gate::class,
        'Hash' => Illuminate\Support\Facades\Hash::class,
        'Lang' => Illuminate\Support\Facades\Lang::class,
        'Log' => Illuminate\Support\Facades\Log::class,
        'Mail' => Illuminate\Support\Facades\Mail::class,
        'Notification' => Illuminate\Support\Facades\Notification::class,
        'Password' => Illuminate\Support\Facades\Password::class,
        'Queue' => Illuminate\Support\Facades\Queue::class,
        'Redirect' => Illuminate\Support\Facades\Redirect::class,
        'Redis' => Illuminate\Support\Facades\Redis::class,
        'Request' => Illuminate\Support\Facades\Request::class,
        'Response' => Illuminate\Support\Facades\Response::class,
        'Route' => Illuminate\Support\Facades\Route::class,
        'Schema' => Illuminate\Support\Facades\Schema::class,
        'Session' => Illuminate\Support\Facades\Session::class,
        'Storage' => Illuminate\Support\Facades\Storage::class,
        'Str' => Illuminate\Support\Str::class,
        'URL' => Illuminate\Support\Facades\URL::class,
        'Validator' => Illuminate\Support\Facades\Validator::class,
        'View' => Illuminate\Support\Facades\View::class,

    ],


定義する場合は、以下のように記載。

#TestController.php

#以下の部分はvenderフォルダの中にlaravelと言うフォルダが入っていてframeworkがあってIlluminateがある。後は順番に見ていく。
use Illuminate\Support\Facades\DB;


Laravel起動処理DIとサービスコンテナ

以下参考記事になります。
https://qiita.com/namizatork/items/801da1d03dc322fad70c

bladeとは

Laravelで組み込まれているテンプレートエンジンのこと。
bladeビューにはファイル名に.blade.phpをつける。

例:welcome.blade.phpの場合

#@ifと@endifやログイン機能用の@authと@endauthなど

<body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth
//以下のような{{}}は文はXSS攻撃を防ぐために、PHPのhtmlspecialchars関数を自動的に通されます
                        <a href="{{ url('/home') }}">Home</a>
                    @else
                        <a href="{{ route('login') }}">Login</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}">Register</a>
                        @endif
                    @endauth
                </div>
            @endif

フロントエンドに向けて

※設定が必要だがインストールした際に以下のものはファイルが既に存在するものもある。

laravel-ui ...Laravel6.xから
laravel-mix...webpackのラッパー
webpack.mix.js...laravel-mixの設定ファイル
Node.js/npm...別途インストール
package.json/package.lock 設定ファイル

#webpack.mix.js

//laravel-mixの記載あり
const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */


//'resources/js/app.js'は元のファイルでそれを'public/js'に1個にまとめて入れている。'resources/sass/app.scss'は元のファイルでそれを'public/css'にに1個にまとめて入れている

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

Laravel-uiと認証

Laravel6からフロント側が分離された。uiはユーザーインタフェース。

LaravelはJavaScriptやCSSプリプロセッサの使用を規定してはいませんが、開発時点の元としてほとんどのアプリケーションで役立つだろうBootstrapやReact、Vueを提供しています。これらのフロントエンドパッケージをインストールするため、LaravelはNPMを使用しています。

Laravelが提供するBootstrapとVueのスカフォールドは、Composerを使いインストールするlaravel/uiパッケージに用意してあります。

//laravel6の場合
$ composer require laravel/ui:^1.0 --dev
$ composer require laravel/ui "^1.2"

//laravel7の場合
$ composer require laravel/ui:^2.4 --dev

laravel/uiパッケージをインストールできたら、ui Artisanコマンドを使いフロントエンドのスカフォールドをインストールします。

// 基本的なスカフォールドを生成
php artisan ui bootstrap
php artisan ui vue
php artisan ui react
// ログイン/ユーザー登録スカフォールドを生成
php artisan ui bootstrap --auth
php artisan ui vue --auth
php artisan ui react --auth
vue.js+bootstrapの場合
$ composer require laravel/ui
$ php artisan ui vue --auth
$ npm install bootstrap-vue bootstrap

import BootstrapVue from 'bootstrap-vue';
Vue.use(BootstrapVue);
$ npm install && npm run dev

//補足
$ npm run dev ・・開発用にビルド
$ npm run watch ・・常時ビルド
$ npm run prod ・・本番用にビルド

新規登録後の移行先を変更

RegisterControll.php
#before homeを消す
protected $redirectTo = '/home';

#after
protected $redirectTo = '/';

ログイン後の移行先を変更

//laravel6の場合
loginControll.phpファイル

#before homeを消す
protected $redirectTo = '/home';

#after
protected $redirectTo = '/';


//larvel6.8以降の場合
Providers/RouteServiceProvider.phpファイル

エラーメッセージの日本語化

resources/lang/elの中のファイルにエラーメッセージの記載あり。
https://github.com/minoryorg/laravel-resources-lang-ja
解凍してjaフォルダをコピーして既存のフォルダに格納する。

日本語か英語かの設定はconfigのapp.phpに記載がある。
83行目の 'locale' => 'ja',
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Twig よく使う書き方まとめ

経緯

EC-CUBEを使用する案件でTwigを使用する機会があり、そもそもTwigとはなんぞや状態だったので、簡単にまとめてみました。

Twigとは?

Twigは簡素で読みやすいデザイナーにもフレンドリーなPHPテンプレート言語です。
以下、Twigでよく使う書き方の一例です。

コメントアウト
index.twig
{#コメント#}
変数の取得
index.twig
{{変数}}
配列の取得
index.twig
{{変数名,キー名}}
変数の作成
index.twig
{% set 変数名 =  %}
条件分岐処理
index.twig
{% if 条件式 %}
...
{% endif %}
繰り返し処理
index.twig
{% for 条件式 %}
...
{% endfor %}
値の出力
index.twig
{{dump(変数名など)}}
フィルター処理
index.twig
{{処理したいデータ[フィルター名]}}
ブロック処理
index.twig
{% block ブロック名 %}
...
{% endblock %}
継承処理
index.twig
{% extends 'ファイルパス' %}
挿入処理
index.twig
{% include 'ファイルパス' %}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Composerでプロジェクトを作ってみた

概要

Composerを使ってDB触れる簡単なCLIを作りたかったのでComposerで作ってみました。

成果物はgithub.com、なお実際にDB触る部分は入れてません。

作り方


1. composer init でプロジェクトを作成
2. composer require [パッケージ名] でパッケージを入れる
3. 名前空間を作る場合、 composer.json に以下のセクションを作成
1. リファレンス: getcomposer.org

composer.json
"autoload": {
    "psr-4": {
        "App\\": "src/App" // 名前空間と対応するパス
    },
    "classmap": [
        "src/App" // クラスを読み込むディレクトリのルート
    ]
}
  1. autoloadclass_alias などを設定する bootstrap.php を適当に作成
    1. この bootstrap.php は適当なphpから require_once などで読み込む事で使います
  2. phpunit を組み込む場合
    1. composer require --dev phpunit/phpunit でインストール
    2. composer.json に以下のセクションを作成
composer.json
    "scripts": {
        "test": [
            "phpunit --bootstrap bootstrap.php test"
        ]
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む