20200327のPHPに関する記事は9件です。

GoogleスプレットシートのデータをWordPressのMySQLにコピーする方法【PHPでまるっと処理】

Googleスプレットシートのデータを、WordPressのMySQLにコピーする方法を説明します。

スプレットシートのデータをWordPressのMySQLにコピーする方法

PHPファイルでまるっと処理しますが、スプレットシートを公開してJSONファイルでデータを取得可能にした上で、WordPressのサーバからJSONを取得しにいって、MySQLにデータを流し込んでいくというのが大まかな流れです。

前提(データセットとスプレットシートの下処理)

【例として扱うデータセット】
過去記事でも扱っているGoogleフォームで募った会議参加者の情報を管理することを例にあげます。

(過去記事)
Googleフォームで取得した画像をスプレットシートで表示する方法【セル内に画像で表示】

(参考)
今回扱うデータはこちらにて公開しておりますので、必要に応じてコピペして使ってください。データセットとして{image, name, birthplace, performance}の4つを扱います。
Screen-Shot-2019-12-08-at-19.48.57.png

WordPress側の独自テーブルの作成にあたっては、必要に応じて以下を参照してください。wp_member_listという独自テーブルを作成しています。

(その他 参考記事)
WordPressのMySQL独自テーブルの作成と利用方法【wp-db.phpの更新必須】

【スプレットシートの公開】
スプレットシートに外部からアクセスできるように公開する必要があります。(取り扱うデータの観点から、公開先を限定する必要があればSpreadSheet APIを活用してください。)

wordpress_mysql_from_spreadsheet_01.jpg

その上で、スプレットシートをJSONで取得できるURLを作成します。公開したスプレッドシートのIDを、黄色下線部の部分に指定してください。

Screen Shot 2020-03-27 at 23.53.01.png

きちんとJSON取得用のURLになっていると、ブラウザでアクセスした際にスプレットシートの結果が返ってくることが確認できます。

wordpress_mysql_from_spreadsheet_02.jpg

データをコピーするPHPスクリプト

以下のPHPコードにて、スプレットシートからデータ取得を行って、MySQLへデータを格納します。

sample.php
<?php

require_once(dirname(__FILE__) . "../../../../wp-load.php"); //実行環境に合わせてパスを設定

// スプレットシートからJSONの値を取得
$data = "https://spreadsheets.google.com/feeds/list/1SZCuyk2H7FBOxoeLp93imOlUxjBu2gBFhUpHk_PVaBc/od6/public/values?alt=json";
$json = file_get_contents($data);
$json_decode = json_decode($json);
$names = $json_decode->feed->entry;

global $wpdb;

// スプレットシートの行ごとに処理を繰り返す
foreach ($names as $name) {

    // JSONからそれぞれの値を取り出す
    $m_image = $name->{'gsx$image'}->{'$t'};
    $m_name = $name->{'gsx$name'}->{'$t'};
    $m_birthplace = $name->{'gsx$birthplace'}->{'$t'};
    $m_performance = $name->{'gsx$performance'}->{'$t'};

    // JSONから取り出した値を独自テーブル(member_list)へinsertする
    $wpdb->insert($wpdb->member_list, array(
        'image' => $m_image,
        'name' => $m_name,
        'birthplace' => $m_birthplace,
        'performance' => $m_performance
        ), array('%s', '%s', '%s','%s',));
}
return;

正しく実行できていれば、準備しておいた独自テーブル(WordPressのホスティングサーバのMySQL内)の中に、スプレットシートから取得したデータが格納されていることが確認できると思います。

b_spreadsheet_demo_insert.php_03.jpg

上手くいかない場合は、スプレットシートの公開設定や過去記事に記載したWordPressのMySQLで独自テーブルを設定する方法について確認してみてくださいね。

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

PHPの文と式

このスライドは突発で開催されたPHPerKaigi Online(仮)でしゃべるために用意されたものです。


前回のあらすじ


PHPカンファレンス関西2020 【公募セッション募集について】 今年も例年どおりPHPカンファレンス関西では公募セッション枠として、有志PHPerの皆様からセッションのスピーカーを募集します。 ※LTのスピーカー募集については後日発表予定です。


コードを自在に操るためのPHP文法入門

PHPのソースコードを正確に検査したり、ソースコードの一部を書き換えたいと思ったことはありませんか? PHPにはPHP-Parserという構文解析ライブラリがあり、静的解析ツールのPHPStanやリファクタリングツールのRectorはPHP-Parserをベースにしたプラグインでソースコードを検査したり、ソースコードを書き換えたりすることができます。

しかしながら、構文木を操作するには普段何気なくPHPコードを書く以上のプログラミング言語についての知識が求められます。この発表では構文木を取り扱う前提となるプログラミング言語についての知識、PHP-Parserの構造、PHPStanとRectorそれぞれの拡張方法と実例についても紹介します。


誠に残念ではございますが、新型コロナウイルスの感染拡大を鑑み、PHPカンファレンス関西2020の開催を断念することになりました。楽しみにして頂いた皆様に心よりお詫び申し上げます。公式サイトの告知は追って更新します。


:cry:


気をとりなおして


こういう記事を先週書きました

Qiita echoとprintの違い


echoとprintの違いを要約すると

  • 関数マニュアルに載っているが関数ではない
  • echoprintは出力バッファに書き込む
  • echoだがprint
  • echoは複数の引数、printは1つの引数

echoだがprint


というわけで、今回は文と式に絞って話をします


クイズ


syntaxエラーにならないのはどちらでしょう。

echo print 1;
print echo 1;

プログラミング言語を習うと初めにこういうことを習う


入門者に叩き込まれる謎の用語

  • if文で条件分岐をします
  • for文で繰り返します
  • 代入文で変数に値を入れます
  • return文で関数から値を返します

たいていの人は、それが何なのか悩む前に使いかたをマスターしてしまうので何も困らない


PHPにはいろんな文と式がある


キーワードのリスト

PHPマニュアルに載っているPHPのキーワード(予約語)のリスト


このリストには文と式がごちゃごちゃに載っている


プログラムの構成要素を分解してみよう


PHPの場合

<?php

function sum(array $values)
{
    $sum = 0;

    foreach ($values as $v) {
        $sum += $v;
    }

    return $sum;
}

意味をつけていく

<?php // ← PHP開始タグ

function sum(array $values) // ← 関数定義
{
    $sum = 0; // 変数代入

    foreach ($values as $v) { // foreach
        $sum += $v; // 変数代入
    }

    return $sum; // 戻り値
}

文と式を分けていく

<?php // ← PHP開始タグ(特殊)

function sum(array $values) // ← 関数定義「文」
{
    $sum = 0; // 変数代入「式」

    foreach ($values as $v) { // foreach「文」
        $sum += $v; // 変数代入「式」
    }

    return $sum; // 戻り値「文」
}

PHPには書く場所が限られる要素がある


PHPではこういうコードは書けない

<?php

const A = hoge();

function a($a = foo())
{
    return $a;
}

PHPではこういうコードは書けない

何を当たり前のことをという

foreach (function a(){return [];} a() as $b) {
    return $b;
}

式(expression, expr)とは何か


式はこんなところに書ける

ここに書けるのは式

  • ifの条件を書くところ if ($v == 1)
  • whileの条件を書くところ while (count($a) !== 0)
  • 関数呼び出しの引数 foo($a + 1)
  • 代入の右辺 $v = 30 * MINUTES
  • return に書けるもの return foo() + bar()
  • echo, print, <?= ?> に渡せるもの

よく使われる式 (その1)

  • 関数・メソッド呼び出し printf() $obj->foo() $func()
  • 演算子式
    • 論理否定 !$foo
    • 比較式 $a == $b $user instanceof User
    • 算術演算 1 + 1
    • 短絡論理演算子 $n <= 0 && $n < 24 foo() or bar()
    • インクリメント・デクリメント $i++ --$i

よく使われる式 (その2)

  • 無名関数式 function ($a) { return $a * 2; } fn($a) => $a * 2
  • 無名クラス new class('foo'){ function __construct($name) { $this->name = $name; } }
  • 配列リテラル [$a, $b, 'foo' => foo()]
  • 三項演算子 $foo == 'bar' ? 'A' : 'B'

よく使われる式 (その3)

  • () 式のグルーピング
  • isset, empty
  • eval
  • assert
    • PHP5では関数だったがPHP7で言語構造になった
  • exit die
  • 変数・スカラーリテラル・定数・マジカル定数

    * $a 1 "a" true HOGE

式の特徴

  • 式の中に再帰的に式を書ける

こんなものも式

  • $a = include __DIR__ . '/config.php'
  • $b = eval('return 1 + 1;')
  • $c = yield 1;
  • $d == 1 or die()
  • $e = foo() and print $e

とてもひどいことに、式の種類によって () が省略可能かどうかがバラバラで、個別に覚えないといけない。(または編集中にsyntax checkする)


式はこんなところにも書けるぞ

  • foreachas の左側
  • foreach (foo() as $f)
  • include, requireの引数
  • 式の中には任意の組み合せの式が書ける
    • ただし [] + 1 のような式はPHP7ではパーサーレベルで怒られるようになった


よく使われる文

  • 関数/メソッド定義文 function
  • クラス定義文 class interface use
  • 制御構文 while for do foreach
  • 出力文 echo <?=
  • 定数定義文 const FOO = 1;
  • インポート文 use use function use const use ... as

文にはこんなものもある

  • キャスト (int) (string) (bool)
  • トレイトの追加 use
  • 実行ディレクティブ declare(strict_types=1);
  • HTML出力 ?><?php の外側
  • 静的変数 static $var
  • グローバル変数 global $var

文の分類


文の特徴

  • 式は任意の式を組み合わせられる
  • 文は文ごとに決まったルールがある
    • 式を書けるもの
    • 式と文を書けるもの
    • それ以外の記述ができるもの

式文

式だけで構成される。;または?>で終端する。

<?php
require_once ___DIR__ . '/foo.php'; // require 式だけの文
$n = 100; // 代入式だけの文
printf("%f", 1.1); // 関数呼び出しだけの文
assert($n < 100); // assert式だけの文
print 1; // print 式だけの文

複文

複数の文が書ける。普通はifforeachと組み合わせて使う。

{
    foo();
    bar();
}

条件文 if, else, elseif

このには文を一つだけ書けるが、通常は if ($cond) echo 1; のように {} を付けずに書くことは好まれず、 if (true) { echo 1; } のように複文を使って改行して書くことが好まれる。

if () 
if ()  else  
if ()  elseif () 
if ()  elseif ()   else  

別構文

if ():  endif;
if ():  else:  endif;
if ():  elseif: ()  endif;
if ():  elseif: ()   else  endif;

繰り返し while

while () 

別構文

while ():  endwhile;

複雑な繰り返し for

for (最初に実行される式; 継続判定式; 繰り返しごとに実行される式) 

別構文

for (最初に実行される式; 継続判定式; 繰り返しごとに実行される式):  endfor;


特別な式が書ける文

  • 静的に解決できる式だけ書ける (PHP 7)
    • const
    • プロパティ
const SEC = 1;`
const MINUTES = 60 * SEC;
const HOUR = 60 * MINUTES;

クイズの解答


echo print 1; // echo は文なので式(print)を引数にとれる
print echo 1; // echo は文なので式(print)の引数に書けない
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

受託Webサイト制作の時の開発環境

今回の開発環境の備忘録と次点として生かそうと思い投稿しておきます。

前提

案件

ボリューム:20ページくらい
納期:2週間くらい
備考:レスポンシブ(SP版のデザインはなく良い感じに)

業務フロー

コーディング→ローカル確認→テスト環境アップ(WebサーバにFTPソフトで)

開発環境(マシン、サーバ)

MacOS
MAMP

開発リソース

php
css
js
assets(image, font, etc)

コンパイル

Macのシェルスクリプトでコピーやsassを走らせて成果物を作る。
具体的には、CPコマンドやインストールしたsassコマンドでsrcディレクトリからdistディレクトリに吐き出していく。watch機能もつけた。

ディレクトリ構成

site/
- dist/
  - index.php(home)
  - _section.php(home)
  - detail/(page)...etc
  - css
    - home.css...etc
  - js
    - home.js...etc
  - common
    - header.php
    - footer.php...etc
- src/
  - assets/
  - js/
    - common/
      - lib/
        - bxSlider.js...etc
    - page/
      - home
  - scss/
    - common/
    - page/
      - home
        - style.scss
        - _section.scss...etc
  - template/
    - common/
    - page/
      - home/
        - index.php
        - _section.php...etc
- compile.sh
- watch.sh

考察

まずコンパイルについては、
sass以外は、ほとんどコピーなので、コンパイルする必要性がなかった。
わかりやすくするためにcss以外のリソースも一緒にコンパイルしていたが、最初から必要はなかった。そのためコンパイルに余計な時間が取られたと思う。
ただ、個人的には開発リソースと成果物は分けるべきとは思っているので、今回のコンパイルは悪くないと思っている。
実際、jsの圧縮やphpテンプレートに自動でリソースパスを渡すなどの機能もつけやすくなると思っている。
一つ悪いポイントは、納期がパツパツ過ぎたため、余計なこと考える余裕もないし、実装する時間もないため、余計な機能になってしまったことだと思う。
実務ではそこも重要なポイントであるので、設計はほんとむずいと改めて思った。

phpは、受託制作に関しては優秀であると再認識した。
正直特にphpの機能を使いこなした訳ではないが、includeと変数だけで、テンプレートを細分化できるので良い。1ページでだいたい処理が完結する(ページ単位でのスコープで良い)ので十分と思っています。

sassはここで言うまでもなくとても良い。コンパイルで変更したファイルだけを見れるようにできたら良いと思った。なんかありそうな気はしてるが。

jsはほぼプラグイン。圧縮するほどの量もないが、がっつりした案件が来た時改め考えたい。もしできるなら、webpackを使ってcssModulesを使いたいのだが、そもそもWebサイト受託でそこまでやることあるかまだ疑問に思っているので保留。

次点

受託制作は、スピード重視かつ壊しやすい設計も必要なので、コンパイルはsassのみで、phpはそのまま編集が良いかなと思いました。
あと、スピード重視のため、cssはflexをめっちゃ多用すべきと思いました。
flexのポリフィルを入れればIE8までは対応できるので、今の時代なら大丈夫な範囲だと思ってます。
あとは、スライダーやスライドショーでbxSlider。

まとめ

  • コンパイルはsassだけで良い
  • phpとcssのflexはスピード開発に良い
  • bxSliderとflexibility.js

大して参考になるお話ではないと思いますが、アプリ開発とサイト制作の違いがあり、どちらにも効率的なやり方があるのだなーと思ったので、残した記事でした。

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

?【PHP】Kubernetesの略称に慣れるためにk8sライク略称を作る関数

この記事は?

ただのネタ記事です
Kubernetesの略称の一つである「K8s」ってのは
Kとsの間が8文字なのでk8sらしいのですがなじみがなかったので関数化しました

環境

PHP 7.2.21

やったこと

k8s.php
    /**
     * K8sライクな略称を作成
     *
     * @param string $name 略する名前
     * @return string 略称/$nameが2文字以下の場合は$nameを返す
     */
    public function makeKubernetesLikeAbbreviation(string $name = ''): string
    {
        $prior     = substr($name, 0, 1);
        $posterior = substr($name, -1);

        $len = strlen($name) -2;

        if ($len <= 0) {
            return $name;
        } else {
            return $prior . $len . $posterior;
        }
    }

返却値

ret.php
// ''
$moji0 = $this->makeKubernetesLikeAbbreviation('');
// 'a'
$moji1 = $this->makeKubernetesLikeAbbreviation('a');
// 'ab'
$moji2 = $this->makeKubernetesLikeAbbreviation('ab');
// 'Q3a'
$moji5 = $this->makeKubernetesLikeAbbreviation('Qiita');
// 'e7r'
$moji9 = $this->makeKubernetesLikeAbbreviation('eltociear');
// 'K8s'
$moji10 = $this->makeKubernetesLikeAbbreviation('Kubernetes');
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

phpでファーストクラスコレクション

phpでファーストクラスコレクションを使ってみる

ファーストクラスコレクション is 何

クラスオブジェクトを独自クラスでコレクション化したもの

メリット

  • オブジェクトの配列を扱うコードが簡単に書けるようになる
  • 配列の子要素をオブジェクトで簡単に書ける
  • オブジェクト配列に対する処理(件数やフィルター)をコレクション側に定義できる
    • 例えば「配列を渡して件数カウントする処理」や「特定の条件に一致するものだけ取得する」ような処理を利用者側が作らなくてよくなる

よくある配列だらけのソース

//DBからなにがしかの一覧を取得
$saleList = Db::getSaleList();

$dataCnt = 0;
$over100List = [];
foreach ( $saleList as $saleData) {
    $dataCnt++;
    if ( $saleData['amount'] >= 100 ) {
       $over100List[] = $saleData;
    }
}

var_dump($dataCnt); //データの個数
var_dump(count($over100List)); //¥100以上のデータの数

ダメなポイント

  • $saleData['amount']を何度も使いまわした後に、キー名をvalueに変えたい!みたいな時に影響範囲が広がる
  • データが無い時とかにkey undefinedとかなりがち。

コレクション化してみる

  class ESaleData { //DBの1レコードに対するエンティティクラス
     public $id = null;
     public $amount = null;

     public function __construct($id, $amount) {
         $this->id = $id;
         $this->amount = $amount;
     }
  }

  /**
  * @return ArrayIterator|ESaleData []
  */
  class ESaleCollection implements ArrayAccess, IteratorAggregate{ //ESaleDataを配列化したクラス
     private $_items = [];
     public function __construct($items) {
         foreach ( $items as $item ) {
            $this-_items[] = new EsaleData($item['id'], $item['amount']);
         }
     }
     /**
      * @return $this|EsaleData[]
      */
     public function filterOver100() {
        $filteredCollection = clone($this); //元のインスタンスに影響しないようにcloneする
        foreach ( $tmpCollection as $key => $saleData) {
           if ( $saleData->amount < 100 ) {
               $filteredCollection ->offsetUnset($key);
           }
        }
        return $filteredCollection;
     }
     public function offsetUnset($offset) {
        unset($this->_items[$offset]);
     }
     public function count() {
         return count($this-_items);
     }
     //IteratorAggregateやらのIFでの必須メソッドは調べてネ。
  }
//DBからなにがしかの一覧を取得
$saleList = Db::getSaleList();
$saleCollection = new ESaleCollection($saleList);

var_dump($saleCollection->count()); //データの個数
var_dump(saleCollection->filterOver100()); //¥100以上のデータの数

効果

  • 利用者側の責務が圧倒的に減る
    • データの個数を求める際にcollectionのcount()を呼ぶだけの隠微化がされる
    • データの条件によるフィルタリング処理も隠微化される
    • データに対する操作がcollection側にまとめられる

コーディングする上での小ネタ

  /**
  * @return ArrayIterator|ESaleData []
  */
  class ESaleCollection implements ArrayAccess, IteratorAggregate{ //ESaleDataを配列化したクラス

このphpDocsが大事。
素直に読むと"ArrayIteratorもしくはEsaleData[]をリターンしますよ"だが、
こう書いておくことでIDE側で"ArrayIteratorでありEsaleData[]である"と判断させることができる
「undefineだが実際は動く」ソースは保守性が低い。できるだけコーディング中から正しく繋ぐべき。

//DBからなにがしかの一覧を取得
$saleList = Db::getSaleList();
$saleCollection = new ESaleCollection($saleList);
foreach ( $saleCollection as $saleData) {
   var_dump($saleData->amount); //phpDocsが定義されていると、このamountは予測変換が効く
}
//DBからなにがしかの一覧を取得
$saleList = Db::getSaleList();
$saleCollection = new ESaleCollection($saleList);
foreach ( $saleCollection as $saleData) {
   /* @var $saleData ESaleData */ //アノテーションする手もあるが本質的ではない
   var_dump($saleData->amount);
}

使ってみて感想

  • 配列のキーの不安感を払拭できる
  • Modelとエンティティ側のメソッドが分離してコードが見やすくなる
    • Fatになりがちなデータ編集処理をCollectionに一任できるのが素晴らしい
  • ベースとなるDBのアクセスやデータフローの設計を理解していないと危なっかしい
  • トータルのソース記述量は増える。心配は減る。

参考

配列の処理をファーストクラスコレクションに組み替えてみる
コレクションオブジェクト/ファーストクラスコレクションについて勉強してみた

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

Laravel + PHPUnitでパスセグメント(パスパラメーター)を再現する

ここのコードは実際には動作しないと思われます。
俺たちは雰囲気でコードを書いている。

例えば以下のようにURLを設定します。

routes.php
Route::get('/{user_id}', 'UserController@show');
Route::get('/{user_id}/edit', 'UserController@edit');
Route::get('/{user_id}/hoge', 'UserController@hoge');
Route::get('/{user_id}/fuga', 'UserController@fuga');

ユーザーが存在しなければ例外とします。
必然的にUserクラスは1つしか存在してはいけないので、ServiceProviderでsingletonにします。

AppServiceProvider.php
public function boot() {
    $this->app->singleton(User::class, function() {
        return (app()->make(UserService::class))
            ->findUser();
    });
}
UserService.php
public function findUser()
{
    $user = User::find(request()->route()->parameter('user_id'));
    if (is_null($user)) {
        throw new NotFoundException('ユーザーが見つかりません');
    }
    return $user;
}

これでどのクラスからでもapp()->make(User::class)でユーザー情報が取得できるようになりました。
なお、あくまで例としてUserクラスを挙げていますが、Laravelでは認証済みユーザーはAuth::user()で取ってこれます。

以下、本題のテストのお話です。

単にリクエストをテストするだけなら簡単です。

Feature/UserTest.php
/**
 * @test
 */
public function ユーザーがいなければ404になること()
{
    $response = $this->get('/should_404');
    $response->assertStatus(404);
}

ではfindUserを単体テストするにはどうすれば良いでしょうか。
単純にfindUserメソッドを呼ぶと、request()->route()の時点でnullが返ってくるため->parameter('user_id')で例外になります。

結論として、事前にRequestを疑似的に再現して対処します。

Unit/UserTest.php
/**
 * @test
 */
public function 指定されたユーザーがいなければNotFoundExceptionになること()
{
    $this->expectException(NotFoundException::class);
    request()->setRouteResolver(function () {
        return (new Route('POST', '/{user_id}', []))->bind(
            new Request([], [], [], [], [], ['REQUEST_URI' => '/should_not_found'])
        );
    });
    (app()->make(UserService::class))->findUser();
}

参考:
Simulate a http request and parse route parameters in Laravel testcase

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

単体テストを記述できる条件(PHP)

はじめに

PHPで書いたプログラムの単体テスト(自動テスト)は通常PHPUnitで実装することになります。

その際にテスト対象となるPHPのクラスはどのように書いてもテストできるわけではなく、一定の条件を満たす必要があります。

主に注意すべきは3点です。

  • コンストラクタ
  • ローカル変数の扱い
  • 静的関数、プロパティの扱い

基本的にはPHPUnitが提供しているMockに置き換えられるかどうかというところが焦点となります。

コンストラクタで複雑な処理を行わない

PHPに限らず大抵のオブジェクト指向のプログラミング言語でもそうなのですが、コンストラクタは他のメソッドよりも制御が難しく、自動テストを記述するのも難しいです。

コンストラクタ内で複雑な処理を実装してしまうと、引数に与えるオブジェクトを除いてMock化することもできないため、テストが記述不能になる可能性が高くなります。

コンストラクタの単体テストが記述できないようなclassの場合、ReflectionClass::newInstanceWithoutConstructor()でコンストラクタを迂回してテスト用のインスタンスを作るといった回避策を取ることもあるでしょう。ただしPHP > 5.4以上ですが。

メソッド内のローカルでnewしない

テスト対象のメソッド内のローカル変数として、外部のクラスのインスタンスを生成していたりすると、そのメソッドはテストを実装不能になります。なぜならば他のクラスのインスタンスが生成された環境であるため、そのクラスのプログラムも動作してしまい、単体テストでなくなってしまうからです。(それは結合テストです)

これは直接newで生成する場合以外も、SomeDao::getInstance()等の静的メソッドでインスタンスを取ってくるケースでも同じことになります。

この問題の回避策としては、外部クラスのインスタンスは一旦全てプロパティに代入し、プロパティ越しにアクセスすることでローカル変数でなくしてしまうことです。

するとプロパティに設定されるはずの外部クラスのインスタンスはPHPUnitが提供するMockに置き換えることができるので、単体テストとして記述できるようになります。

静的関数、プロパティの扱い

静的関数のテストは実質的にそのクラスのインスタンスが存在しない環境(そのメソッド自体でインスタンスを作っている場合を除く)となりますが、基本的なアプローチはこれまでに書いたことと同じです。

ただし、静的関数ではそのクラスのインスタンス別の環境とはならず、システム全体で単一の環境となる(あるいは状態を持たない環境となる)ので、注意して実装する必要はあるでしょう。

以上

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

Laravelでresource使用してる時のroute()とかの一覧

Resource & route()

いつも書き方忘れてハマるので自分用に備忘録

Blade

index(一覧画面)

リンク

<a href="{{ route("user.index") }}">一覧画面へのリンク</a>

create(作成画面)

リンク

<a href="{{ route("user.create") }}">作成画面へのリンク</a>

store(作成処理)

form

<form action="{{ route("user.store") }}" action="post">
    @csrf

show(詳細画面)

リンク

<a href="{{ route("user.show", ["id" => $user_id]) }}">詳細画面へのリンク</a>

edit(編集画面)

リンク

<a href="{{ route("user.edit", ["id" => $user_id]) }}">詳細画面へのリンク</a>

update(更新処理)

form

<form action="{{ route("user.update", ["id" => $user_id]) }}" action="post">
    @csrf
    @method('PUT')

delete(削除処理)

form

<form action="{{ route("user.destroy", ["id" => $user_id]) }}" action="post">
    @csrf
    @method('DELETE')

Controller

UserController

UserController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        return view('user.index');
    }

    public function create()
    {
        return view('user.create');
    }

    public function store(Request $request)
    {
        // 作成処理
    }

    public function show($id)
    {
        return view('user.show', [
            'user_id' => $id
        ]);
    }

    public function edit($id)
    {
        return view('user.edit', [
            'user_id' => $id
        ]);
    }

    public function update(Request $request, $id)
    {
        // 更新処理
    }

    public function destroy($id)
    {
        // 削除処理
    }
}

ルーティング

web.php

web.php
Route::resource('user', 'UserController');

制限する時

web.php
Route::resource('user', 'UserController', ['only' => ['index', 'show']]);
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

本日の学習内容part4

参考記事

yaaabu51さんの【PDO】PHPでデータベースに接続する方法【INSERT編】

調べたメソッド

prepareメソッド⇒prepareの後の括弧内にあるSQL文を実行する準備をする。
executeメソッド⇒SQL文を実行する。
fetchメソッド⇒該当データを1行だけ取得する。

   $messages = $db->prepare('SELECT * FROM posts WHERE id=?');
   $messages->execute(array($id));
   $message = $messages->fetch();

間違えていましたら遠慮なく仰って下さい。m(__)m

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