20201017のPHPに関する記事は30件です。

array_keysとarray_flipの速度を比較してみた

タイトルの通り、速度検証をしたので、どうやってやったかとその結果を記載します。

忙しい人向け結論

array_keysとarray_flipだと、array_keysのほうが速い

本題

経緯

あー特定の文字列が配列のキーに含まれているかチェックしたいなー

in_arrayだと判定対象はvalueだから違うよなー

そうだ!array_flipでkeyとvalueを逆にすればいいんだ!
array_flipの公式ドキュメント

$array = [
    'a' => 'あ',
    'i' => 'い',
    'u' => 'う',
    'e' => 'え',
    'o' => 'お',
];

$needle = 'a';

if (in_array($needle, array_flip($array), true)) {
    // 処理
}

よしできた!(*‘∀‘)

あれ、そういえばarray_keysでキーの配列を作ることもできたよな、、、?
むしろこっちのほうが一般的では、、、?
array_keysの公式ドキュメント

if (in_array($needle, array_keys($array), true)) {
    // 処理
}

こっちでもできた!!!

じゃあ、速度的にはどっちを使ったらいいんだろう?

検証

以下のソースコードで検証しました。
説明は適宜コメントアウトで。

// 実行回数
$count = 1000000;
// 配列から見つけたい文字列
$needle = 'a';
// 検索対象の配列
$array = [
    'a' => 'あ',
    'i' => 'い',
    'u' => 'う',
    'e' => 'え',
    'o' => 'お',
];

// array_keysの速度検証
$st = microtime(true);
for ($i = 0; $i <= $count; $i++) {
    in_array($needle, array_keys($array), true);
}
$end = microtime(true);
$result = '処理:array_keysを' . $count . '回実行' . PHP_EOL;
$result .= '時間:' . ($end - $st) . '秒';
echo $result;

// array_flipの速度検証
$st2 = microtime(true);
for ($i = 0; $i <= $count; $i++) {
    in_array($needle, array_flip($array), true);
}
$end2 = microtime(true);
$result2 = '処理:array_flipを' . $count . '回実行' . PHP_EOL;
$result2 .= '時間:' . ($end2 - $st2) . '秒';
echo $result2;

参照した記事はこちら

検証結果

まず、array_keysの検証結果

$result
処理array_keysを1000000回実行 
時間1.633052110672

なるほど、100万回で1.6秒かかるとのことです。

続いて、array_flipの検証結果

$result2
処理array_flipを1000000回実行 
時間2.6483287811279

なんと!こちらは同じ100万回でも2.6秒かかるそうです。

というわけで、結論。

array_flipよりもarray_keysのほうが速い

以上です。ありがとうございました。
何かアドバイス等あればコメントいただけると嬉しいです。

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

【PHP】array_keysとarray_flipの速度を比較してみた

タイトルの通り、速度検証をしたので、どうやってやったかとその結果を記載します。

忙しい人向け結論

array_keysとarray_flipだと、array_keysのほうが速い

本題

経緯

あー特定の文字列が配列のキーに含まれているかチェックしたいなー1

in_arrayだと判定対象はvalueだから違うよなー

そうだ!array_flipでkeyとvalueを逆にすればいいんだ!
array_flipの公式ドキュメント

$array = [
    'a' => 'あ',
    'i' => 'い',
    'u' => 'う',
    'e' => 'え',
    'o' => 'お',
];

$needle = 'a';

if (in_array($needle, array_flip($array), true)) {
    // 処理
}

よしできた!(*‘∀‘)

あれ、そういえばarray_keysでキーの配列を作ることもできたよな、、、?
むしろこっちのほうが一般的では、、、?
array_keysの公式ドキュメント

if (in_array($needle, array_keys($array), true)) {
    // 処理
}

こっちでもできた!!!

じゃあ、速度的にはどっちを使ったらいいんだろう?

検証

以下のソースコードで検証しました。
説明は適宜コメントアウトで。

// 実行回数
$count = 1000000;
// 配列から見つけたい文字列
$needle = 'a';
// 検索対象の配列
$array = [
    'a' => 'あ',
    'i' => 'い',
    'u' => 'う',
    'e' => 'え',
    'o' => 'お',
];

// array_keysの速度検証
$st = microtime(true);
for ($i = 0; $i <= $count; $i++) {
    in_array($needle, array_keys($array), true);
}
$end = microtime(true);
$result = '処理:array_keysを' . $count . '回実行' . PHP_EOL;
$result .= '時間:' . ($end - $st) . '秒';
echo $result;

// array_flipの速度検証
$st2 = microtime(true);
for ($i = 0; $i <= $count; $i++) {
    in_array($needle, array_flip($array), true);
}
$end2 = microtime(true);
$result2 = '処理:array_flipを' . $count . '回実行' . PHP_EOL;
$result2 .= '時間:' . ($end2 - $st2) . '秒';
echo $result2;

参照した記事はこちら

検証結果

まず、array_keysの検証結果

$result
処理array_keysを1000000回実行 
時間1.633052110672

なるほど、100万回で1.6秒かかるとのことです。

続いて、array_flipの検証結果

$result2
処理array_flipを1000000回実行 
時間2.6483287811279

なんと!こちらは同じ100万回でも2.6秒かかるそうです。

というわけで、結論。

array_flipよりもarray_keysのほうが速い

以上です。ありがとうございました。
何かアドバイス等あればコメントいただけると嬉しいです。


  1. 配列のキーに特定の文字列があるかどうかのチェック方法については、今回やろうとしているin_arrayの第二引数にarray_keysやarray_flipを使うやり方よりも、issetarray_key_existsを使った方がわかりやく、$arrayの要素数によってはパフォーマンスもこちらの方がいいとご指摘をいただきました。そのため、本記事では速度比較をした例、という見方をしていただけますと幸いです。 

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

Moodle 3.9 マニュアル - コースブロック

原文

コースブロック

コースブロックでは、ログインしているユーザーが受講しているすべてのコースを一覧表示し、その間を移動することができます。ブロックのタイトルは「マイコース」と表示され、ワンクリックでコースのホームページにアクセスできます。

CoursesBlockNew.png
CoursesBlockNew.png

Moodleサイト内には「すべてのコースを表示する...」オプションもあります。これによりコースタイプのリストが表示され、クリックするとそのカテゴリ内のすべてのコースが表示されます。このページにはすべてのコースを検索するオプションもあります。

Moodleサイトに新規登録したばかりで、どのコースも履修していない場合、ブロックタイトルに「コースカテゴリ」が表示されます。

学生がコースブロックを使用して未登録のコースを入力すると、登録を求められます。

注意: ナビゲーションブロックには、ユーザーが登録しているすべてのコースのリストも表示されます。
サイト管理設定

コースブロックにはいくつかの設定があり、管理者が管理 > サイト管理 > プラグイン > ブロック > コースリストで変更することができます。

・block_course_list_adminview - 管理者がブロック内で何を見るかを決定します。
・block_course_list_hideallcourseslink - ブロックの下部にある「すべてのコース」リンクを管理者以外から隠すことができます。

関連項目

・Moodleの使用方法 ユーザが自分のコースのみを表示できるようにするには?

カテゴリー ブロック コース サイト管理

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

Moodle 3.9 マニュアル - コースのリストア

原文

コースのリストア

内容

1 コースのバックアップをリストアする
2 コース・カテゴリ管理画面からのリストア
3 一般的なデフォルトのリストア
4 コースのリストアのケイパビリティ
5 関連項目

1 コースのバックアップをリストアする

コースのバックアップファイル(.mbz)は、許可された既存のコース内からリストアすることができます。復元プロセスでは、新しいコースとして復元するか、既存のコースに復元するかを選択できます。

video
コースリストアの概要。(説明はMoodleCloud用ですが、他のサイトにも適用されます)

  1. Boostテーマで歯車メニューをクリックし、「復元」をクリックしてください。そうでなければ、サイト管理 > フロントページ設定 > 復元 (あなたがフロントページの権限を持っている場合) または管理 > コース管理 > 復元 (あなたが復元先の空のコースを持っている場合) に移動してください。
  2. バックアップファイルをアップロードするか、コースのバックアップエリアまたはユーザーのプライベートバックアップエリアにあるファイルを選択し、「復元」をクリックします。
  3. 確認 - すべてが必要なものであることを確認し、[続行]ボタンをクリックします。
  4. 宛先 - コースを新しいコースとしてリストアするか、既存のコースにリストアするかを選択し、[続行] ボタンをクリックします。
  5. 設定 - 必要に応じてアクティビティ、ブロック、フィルター、その他の項目を選択し、次へボタンをクリックします。
  6. スキーマ - 特定の項目を選択/選択解除し、必要に応じてコース名、短縮名、開始日を修正し、次へボタンをクリックします。
  7. レビュー - 必要に応じて [前へ] ボタンを使用して、すべてが必要な通りであることを確認し、[復元の実行] ボタンをクリックします。
  8. 完了 - 続行ボタンをクリックしてください。

注意事項。

  1. ユーザーデータ(フォーラムの投稿など)を使ってコースを復元する場合、ユーザーデータは元の日付を保持しますが、アクティビティとセクションは設定した新しいコースの開始時間に応じて変更されます。
  2. 新しいコースのセクション数が復元するコースよりも少ない場合、余分なセクションは「孤児のアクティビティ」として表示されます。新しいコースのセクションの数を増やして表示できるようにしてください。
  3. 別のMoodleサイトからコースをリストアする場合、「バックアップファイルからユーザ(管理者)をリストアしようとすると競合が発生します」というエラーメッセージが表示される場合、サイト管理 > コース > バックアップ > 一般インポートデフォルトで「管理者の競合解決を許可する」設定を有効にすることができます。
  4. アクティビティからカレンダーイベントを含むコースをリストアする場合、例えば課題の期限日など、これらのイベントはコースをリストアしてからしばらくしてからカレンダーに表示されます。イベントはcronタスクを介してカレンダーに追加されます。複数のコースをリストアする場合、イベントがカレンダーに表示されるまでに時間がかかる可能性があります。

2 コース・カテゴリ管理画面からのリストア

サイト管理 > コース > コースとカテゴリの管理、またはサイト管理 > コース > コースとカテゴリの管理 > (カテゴリ名)にアクセスできる権限を持つユーザーは、ここからコースを復元することができます。

300px-RestoreBoost.png
ブーストテーマ

300px-courserestorecategory.png
非ブーストテーマ

3 一般的なデフォルトのリストア

管理者は、サイト管理の [一般的な復元のデフォルト] でデフォルトを設定し、選択した復元設定をロックすることができます。設定がロックされている場合、コースを復元する際に変更することはできません。

別のコースへの復元と結合、およびコースの内容の復元と削除には、異なるデフォルトを設定することができます。

4 コースリストアのケイパビリティ

リストア時にユーザーを作成
リストアオプションの設定
アクティビティのリストア
コースのリストア
セクションのリストア
インポート対象のファイルからのリストア
リストア時にアクティビティ構成の日付をロールする
バックアップ領域へのファイルのアップロード
ユーザーデータのリストア
自動バックアップからコースをリストア

5 関連項目

ファイルエイリアスのリストア
・管理者はMOOSHを使用して、CLIからコースの一括バックアップとリストアを行うことができます。

カテゴリ バックアップ コース

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

【PHP】初めてのマイグレーション

Laravelでのモデル作成とマイグレーションファイル編集に関する備忘録。

■ モデル作成

モデル作成(※モデル名は、大文字から始まる単数形)
% php artisan make:model モデル名             // app直下にファイル生成
% php artisan make:model Entities/モデル名    // app/Entities下にファイル生成される
% php artisan make:model モデル名 -m -c -r    // モデル、マイグレーション、コントローラーを一気に生成

% php artisan make:model -h                 // どんなオプションがあるか?
  • マイグレーションクラスは、2つのメソッドがある(up、down)。
    • upメソッド : マイグレーション実行時の処理 を記述。
    • downメソッド : ロールバック時の処理を記述(upメソッドの逆)。
作成されるマイグレーションファイルのざっくりイメージ(database/migrations/2020_10_15_012345_create_xxxxx_table.php)
public function up()           // マイグレーション実行時の処理は、up() に記述
  {
    Schema::create('xxxxxs', function (Blueprint $table) {
      $table->increments('id');        // デフォルト
      $table->データ型('カラム名');        // カラム作成
      $table->tinyInteger('gender')->unsigned()->comment('性別 1:男、2:女');
      $table->timestamps();            // デフォルト
    });
  }
public function down()        // ロールバック時の処理は、down() に記述
  {
    Schema::dropIfExists('xxxxxs');    // テーブル削除
    Schema::create('xxxxxs', function (Blueprint $table) {
      $table->dropColumn('カラム名');    // カラム削除
      $table->dropColumn('gender');
    });
  }

よく使うマイグレーション関連のコマンド

マイグレーションに関するコマンド
% php artisan migrate:status              // 状態確認
% php artisan migrate                     // マイグレーション実行
% composer dump-autoload                  // 「クラスが見つかりません」エラーが発生したら、migrateコマンドを再発行してみる
% php artisan migrate:refresh             // 初期化→再実行(マイグレーションファイル追加でエラーが出た時など)
% php artisan migrate:fresh               // 全テーブル削除 →マイグレーション実行
% php artisan migrate:rollback            // ロールバック(1つ前)
% php artisan migrate:rollback --step=2   // ロールバック(戻る位置指定)
% php artisan migrate:reset               // 全マイグレーションをリセット(初期化)

■ マイグレーションファイルのみ作成したいなら

例)マイグレーションファイルのみ作成したい場合
% php artisan make:migration create_boxs_table --create=boxs             // boxsテーブル生成
% php artisan make:migration add_カラム名_to_users_table --table=users     // usersテーブルにカラム追加(既存テーブルを更新)
% php artisan make:migration rename_旧テーブル名_to_新テーブル名_table        // テーブル名変更

// マイグレーションファイルの編集ができたら、実行
% php artisan migrate
% composer require doctrine/dbal     // 注)変更・追加には、変更追加用のパッケージのインストールが必要

■ マイグレーションファイルの書き方

テーブル関連

テーブル
// テーブル名変更
Schema::rename("旧テーブル名", "新テーブル名");

// テーブル削除
Schema::drop('users');
Schema::dropIfExists('users');     // テーブルがあれば削除して、なければ何もしない(エラー回避)

カラム関連

カラム追加・削除

カラム追加・削除
// カラム追加
$table->カラム型('カラム名');
$table->string('カラム名');

// カラム削除
$table->dropColumn('削除したいカラム名');
$table->dropColumn(['削除したいカラム名1', '削除したいカラム名2',..]);   // 複数のカラムを削除したい場合は、配列で渡す
  • カラム削除のコマンド
削除コマンド 説明
$table->dropRememberToken( ); remember_tokenカラム(Eloquent認証ドライバーを扱うためのカラム )
$table->dropSoftDeletes( ); deleted_atカラム(ソフトデリート用のNULL可能なカラム)
$table->dropSoftDeletesTz( ); ↑ と同義
$table->dropTimestamps( ); created_atとupdated_atカラム
$table->dropTimestampsTz( ); ↑ と同義
  • ソフトデリートとは?
    • 論理削除のこと。データは削除せず、データを削除したものをして取り扱う。

カラム変更

  • カラム変更前に、composer.jsonファイルでdoctrine/dbalの追加が必要。
    • 現在の状態を決め、指定カラムの修正を行うSQLクエリ生成に使われる。
composer require doctrine/dbal
カラム変更
// カラム名変更
$table -> renameColumn('以前のカラム名', '新しいカラム名');

// カラム属性の変更
$table->string('name', 50) -> change();                 // nameカラムのサイズ変更
$table->string('name', 50) -> nullable() -> change();   // NULLを許可する場合
  • chengeメソッド : カラム型、属性の変更。

インデックスや制約など

インデックス

  • Laravelでは、デフォルトで意味が通る名前をインデックスに付ける。
    • インデックス名 : テーブル名_インデックスしたカラム名_インデックスタイプ

インデックス 【追加】

インデックス追加コマンド 概要 使用例
index('カラム名') インデックス追加 $table->integer('category_id')->index('category_id');
unique('カラム名') ユニークキー追加 $table->unique('email');、$table->string('email')->unique();
primary('id'); 主キー追加 $table->primary('id');
primary(['id', 'parent_id']); 複合キー追加 $table->primary(['id', 'parent_id']);
spatialIndex('カラム名'); 空間インデックス追加(SQLite以外) $table->spatialIndex('location');

インデックス 【削除】

  • インデックス削除は、インデックス名を指定する。
インデックス削除コマンド 概要
$table->dropIndex('テーブル名_カラム名 _index'); インデックス削除
$table->dropUnique('テーブル名_カラム名 _unique'); ユニークキー削除
$table->dropPrimary('テーブル名_id _primary'); 主キー削除
$table->dropSpatialIndex('テーブル名_カラム名 _spatialindex'); 空間インデックス削除(SQLite以外)
  • カラムの配列をインデックスの削除メソッドに渡すと、インデックス名が自動生成される。
例)インデックス削除
$table -> dropIndex(['content']);   // 例) boxs_content_index

外部キー

外部キー 【追加】

  • 紐づけたいテーブルのid(unsined(符号無し))と同様の制約をつけないと形式不一致でエラーになるので注意。
既存カラムを外部キーにする(紐づける)場合
例)既存のuser_idカラムを外部キーにする
$table->integer('user_id')->unsigned()->change();                  // 符号無し属性に変更
$table->foreign('user_id')->references('id')->on('users');         // 外部キー参照
新規カラムとして、外部キーを作成する場合
例)usersテーブルのidカラムを使って、postsテーブルにuser_idカラムを定義する
Schema::table('posts', function (Blueprint $table) {
  $table->integer('user_id')->unsigned();                           // 符号無し属性を作成
  $table->foreign('user_id')->references('id')->on('users');        // 外部キー参照
});

外部キー 【削除】

  • dropForeignメソッド : 他のインデックスと似た命名規則。
  • テーブル名_カラム名_foreign
外部キーの削除
$table->dropForeign('posts_user_id_foreign');
$table->dropForeign(['user_id']);              // 配列で渡せば、命名規則に従った名前が使用される
  • 参)マイグレーション中の外部キー制約を一時的に、有効/無効化ができるメソッドも用意されてる。
    • 外部キー制約を無効にしてDBを操作し、終わったら有効に戻すような時に使う。
参)外部キー制約の有効/無効化の変更
Schema::enableForeignKeyConstraints();    //外部キー制約を有効化
Schema::disableForeignKeyConstraints();   //外部キー制約を一時的に無効化

マイグレーション関連のエラー

MySQL接続エラー: SQLSTATE[HY000][2002]No such file or directory

[PDOException]
SQLSTATE[HY000] [2002] No such file or directory

  • DBに接続できていないエラー。
  • (原因例)
    • .envファイルとMySQL(DB)の、DB_DATABASE、DB_USERNAME、DB_PASSWORDが異なる。
    • .envファイルの修正後、キャッシュをクリアできてない。
    • rootユーザーのPW変更後に、MySQLを再起動してない。
    • MySQLソケットに関するファイル(mysql.sock)が読み込まれてない。 → database.phpで unix_socket を設定する。
ターミナルからunix_socketを確認
// MySQL
% show variables like '%sock%';
            :
 | socket | /Applications/MAMP/tmp/mysql/mysql.sock |
unix_socketの設定(database.php)
'mysql' => [
  'driver'      => 'mysql',
  'host'        => 'localhost',
          : 
  'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock', 
],

■ カラム型 一覧

コマンド 概要
increments('id'); 符号なしの数値(INT)を使ったID(主キー)。0〜4294967295。
bigIncrements('id'); 符号なしのBIGINTを使ったID(主キー)。0〜18446744073709551615。※ 21億行以上にならないなら、↑ を使う。
tinyInteger('numbers'); 数値(TINYINT型)。1バイト
smallInteger('カラム名'); 数値(SMALLINT型)。2バイト
mediumInteger('カラム名'); 数値(MEDIUMINT型)。3バイト
integer('カラム名'); 数値(INT型)。4バイト
bigInteger('カラム名'); 数値(BIGINT型)。8バイト
float('カラム名', ○, △); トータルで8桁、小数点以下2桁以内の小数
double('カラム名', ○, △); トータルで15桁、小数点以下8桁以内の小数
decimal('カラム名', ○, △); トータルで5桁、小数点以下2桁以内の小数
char('カラム名', 5); 固定長文字列(長さが決まってる文字列)
string('カラム名'); 可変長文字列。デフォルトの最大文字数:255文字
string('カラム名', 100); 最大文字数指定の可変長文字列
text('カラム名'); 文字列。65,535文字(約64Kバイト)
mediumText('カラム名'); 長い文字列。16,777,215文字(約16Mバイト)
longText('カラム名'); めっちゃ長い文字列。4,294,967,295文字(約4Gバイト)
date('カラム名'); 日付
time('カラム名'); 時間
timeTz('カラム名'); 時間(タイムゾーン付き)
dateTime('カラム名'); 日時
dateTimeTz('カラム名'); 日時(タイムゾーン付き)
boolean('カラム名')->default(false); 真偽値
enum('カラム名', ['定数', '定数']); enum型
binary('カラム名'); バイナリデータ
json('カラム名'); JSON
jsonb('カラム名'); JSONB
timestamp('カラム名'); タイムスタンプ
timestampTz('カラム名'); タイムスタンプ(タイムゾーン付き)
timestamps(); created_atとupdated_at
nullableTimestamps(); ↑と同じ(NULLを許可)
softDeletes(); NULL可能な deleted_at カラム。例:退会日時などの管理用途(nullでなければ、退会済)
ipAddress('カラム名'); IPアドレス
macAddress('カラム名'); MACアドレス
rememberToken(); Eloquent認証ドライバーを扱うためのカラム。remember_tokenVARCHAR(100)NULLとして追加
uuid('id'); UUID。重複の可能性が小さく、一意な識別子として扱えるID
morphs('カラム名'); 符号なし数値(taggable_id)と文字列(taggable_type)を追加

■ オプション(カラム修飾子)一覧

カラム修飾子 概要
->comment('コメント内容') コメント追加(MySQLのみ)
->nullable() NULL許可
->unsigned() 整数カラムを符号なしに設定(MySQLのみ)。外部キーでよく使う
->default('値')、->default($value) デフォルト値を設定
->first() テーブルの最初(first)に設置(MySQLのみ)
->after('カラム名') 指定カラムの次にカラム追加(MySQLのみ)
->autoIncrement() 整数カラムをID(主キー)に設定
->charset('utf8') キャラクタセットを指定(MySQLのみ)
->collation('utf8_unicode_ci') コロケーションを指定(MySQL/SQL Serverのみ)
->nullable($value = true)、->nullable()->default(null) デフォルトでNULL値を指定
->storedAs($expression) stored generatedカラムを生成(MySQLのみ)
->useCurrent() TIMESTAMPカラムのデフォルト値をCURRENT_TIMESTAMPに指定
->virtualAs($expression) virtual generatedカラムを生成(MySQLのみ)

■ データの作成

  • テーブルが作成できたら、データを作成してみる。

seederで初期値を作成する場合

例)UsersTableSeeder.php生成
% php artisan make:seeder UsersTableSeeder        // UsersTableSeeder.phpが生成される
database/seeds/UsersTableSeeder.php
public function run(){
  DB::table('users')->insert([
    'name' => 'ユーザー1',
    'email' => 'ユーザー1@gmail.com',
    'password' => bcrypt('ユーザー1') 
  ]);
}
database/seeds/DatabaseSeeder.php
public function run()
{
  // $this->call(UsersTableSeeder::class);   // コメントアウトする
}
seederから、データを作成する
% php artisan db:seed --class=UsersTableSeeder     // データ作成
% php artisan tinker                               // 作成したデータの確認
  >>> use App\User
  >>> User::all()

コンソール操作でレコードを作成する場合

ターミナル操作で作成する方法
% php artisan tinker               // コンソール起動
  // レコード作成( インスタンスを作成して、saveメソッドを使う )
  >>> $box = new App\Box();        // インスタンス作成(※ 名前空間がデフォルトでAppなので、App\モデル名(); )
  >>> $box -> title = 'タイトル1';
  >>> $box -> content = '詳細1';
  >>> $box -> save();              // 保存
  => true                         // レコード作成成功

  >>> App\Box::all();             // 作成したデータの確認
  >>> App\Box::all()->ToArray();  // 作成したデータの確認(配列で取得)
  >>> exit
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Laravel】初めてのマイグレーション

Laravelでのモデル作成とマイグレーションファイル編集に関する備忘録。

■ モデル作成

モデル作成(※モデル名は、大文字から始まる単数形)
% php artisan make:model モデル名             // app直下にファイル生成
% php artisan make:model Entities/モデル名    // app/Entities下にファイル生成される
% php artisan make:model モデル名 -m -c -r    // モデル、マイグレーション、コントローラーを一気に生成

% php artisan make:model -h                 // どんなオプションがあるか?
  • マイグレーションクラスは、2つのメソッドがある(up、down)。
    • upメソッド : マイグレーション実行時の処理 を記述。
    • downメソッド : ロールバック時の処理を記述(upメソッドの逆)。
作成されるマイグレーションファイルのざっくりイメージ(database/migrations/2020_10_15_012345_create_xxxxx_table.php)
public function up()           // マイグレーション実行時の処理は、up() に記述
  {
    Schema::create('xxxxxs', function (Blueprint $table) {
      $table->increments('id');        // デフォルト
      $table->データ型('カラム名');        // カラム作成
      $table->tinyInteger('gender')->unsigned()->comment('性別 1:男、2:女');
      $table->timestamps();            // デフォルト
    });
  }
public function down()        // ロールバック時の処理は、down() に記述
  {
    Schema::dropIfExists('xxxxxs');    // テーブル削除
    Schema::create('xxxxxs', function (Blueprint $table) {
      $table->dropColumn('カラム名');    // カラム削除
      $table->dropColumn('gender');
    });
  }

よく使うマイグレーション関連のコマンド

マイグレーションに関するコマンド
% php artisan migrate:status              // 状態確認
% php artisan migrate                     // マイグレーション実行
% composer dump-autoload                  // 「クラスが見つかりません」エラーが発生したら、migrateコマンドを再発行してみる
% php artisan migrate:refresh             // 初期化→再実行(マイグレーションファイル追加でエラーが出た時など)
% php artisan migrate:fresh               // 全テーブル削除 →マイグレーション実行
% php artisan migrate:rollback            // ロールバック(1つ前)
% php artisan migrate:rollback --step=2   // ロールバック(戻る位置指定)
% php artisan migrate:reset               // 全マイグレーションをリセット(初期化)

■ マイグレーションファイルのみ作成したいなら

例)マイグレーションファイルのみ作成したい場合
% php artisan make:migration create_boxs_table --create=boxs             // boxsテーブル生成
% php artisan make:migration add_カラム名_to_users_table --table=users     // usersテーブルにカラム追加(既存テーブルを更新)
% php artisan make:migration rename_旧テーブル名_to_新テーブル名_table        // テーブル名変更

// マイグレーションファイルの編集ができたら、実行
% php artisan migrate
% composer require doctrine/dbal     // 注)変更・追加には、変更追加用のパッケージのインストールが必要

■ マイグレーションファイルの書き方

テーブル関連

テーブル
// テーブル名変更
Schema::rename("旧テーブル名", "新テーブル名");

// テーブル削除
Schema::drop('users');
Schema::dropIfExists('users');     // テーブルがあれば削除して、なければ何もしない(エラー回避)

カラム関連

カラム追加・削除

カラム追加・削除
// カラム追加
$table->カラム型('カラム名');
$table->string('カラム名');

// カラム削除
$table->dropColumn('削除したいカラム名');
$table->dropColumn(['削除したいカラム名1', '削除したいカラム名2',..]);   // 複数のカラムを削除したい場合は、配列で渡す
  • カラム削除のコマンド
削除コマンド 説明
$table->dropRememberToken( ); remember_tokenカラム(Eloquent認証ドライバーを扱うためのカラム )
$table->dropSoftDeletes( ); deleted_atカラム(ソフトデリート用のNULL可能なカラム)
$table->dropSoftDeletesTz( ); ↑ と同義
$table->dropTimestamps( ); created_atとupdated_atカラム
$table->dropTimestampsTz( ); ↑ と同義
  • ソフトデリートとは?
    • 論理削除のこと。データは削除せず、データを削除したものをして取り扱う。

カラム変更

  • カラム変更前に、composer.jsonファイルでdoctrine/dbalの追加が必要。
    • 現在の状態を決め、指定カラムの修正を行うSQLクエリ生成に使われる。
composer require doctrine/dbal
カラム変更
// カラム名変更
$table -> renameColumn('以前のカラム名', '新しいカラム名');

// カラム属性の変更
$table->string('name', 50) -> change();                 // nameカラムのサイズ変更
$table->string('name', 50) -> nullable() -> change();   // NULLを許可する場合
  • chengeメソッド : カラム型、属性の変更。

インデックスや制約など

インデックス

  • Laravelでは、デフォルトで意味が通る名前をインデックスに付ける。
    • インデックス名 : テーブル名_インデックスしたカラム名_インデックスタイプ

インデックス 【追加】

インデックス追加コマンド 概要 使用例
index('カラム名') インデックス追加 $table->integer('category_id')->index('category_id');
unique('カラム名') ユニークキー追加 $table->unique('email');、$table->string('email')->unique();
primary('id'); 主キー追加 $table->primary('id');
primary(['id', 'parent_id']); 複合キー追加 $table->primary(['id', 'parent_id']);
spatialIndex('カラム名'); 空間インデックス追加(SQLite以外) $table->spatialIndex('location');

インデックス 【削除】

  • インデックス削除は、インデックス名を指定する。
インデックス削除コマンド 概要
$table->dropIndex('テーブル名_カラム名 _index'); インデックス削除
$table->dropUnique('テーブル名_カラム名 _unique'); ユニークキー削除
$table->dropPrimary('テーブル名_id _primary'); 主キー削除
$table->dropSpatialIndex('テーブル名_カラム名 _spatialindex'); 空間インデックス削除(SQLite以外)
  • カラムの配列をインデックスの削除メソッドに渡すと、インデックス名が自動生成される。
例)インデックス削除
$table -> dropIndex(['content']);   // 例) boxs_content_index

外部キー

外部キー 【追加】

  • 紐づけたいテーブルのid(unsined(符号無し))と同様の制約をつけないと形式不一致でエラーになるので注意。
既存カラムを外部キーにする(紐づける)場合
例)既存のuser_idカラムを外部キーにする
$table->integer('user_id')->unsigned()->change();                  // 符号無し属性に変更
$table->foreign('user_id')->references('id')->on('users');         // 外部キー参照
新規カラムとして、外部キーを作成する場合
例)usersテーブルのidカラムを使って、postsテーブルにuser_idカラムを定義する
Schema::table('posts', function (Blueprint $table) {
  $table->integer('user_id')->unsigned();                           // 符号無し属性を作成
  $table->foreign('user_id')->references('id')->on('users');        // 外部キー参照
});

外部キー 【削除】

  • dropForeignメソッド : 他のインデックスと似た命名規則。
  • テーブル名_カラム名_foreign
外部キーの削除
$table->dropForeign('posts_user_id_foreign');
$table->dropForeign(['user_id']);              // 配列で渡せば、命名規則に従った名前が使用される
  • 参)マイグレーション中の外部キー制約を一時的に、有効/無効化ができるメソッドも用意されてる。
    • 外部キー制約を無効にしてDBを操作し、終わったら有効に戻すような時に使う。
参)外部キー制約の有効/無効化の変更
Schema::enableForeignKeyConstraints();    //外部キー制約を有効化
Schema::disableForeignKeyConstraints();   //外部キー制約を一時的に無効化

マイグレーション関連のエラー

MySQL接続エラー: SQLSTATE[HY000][2002]No such file or directory

[PDOException]
SQLSTATE[HY000] [2002] No such file or directory

  • DBに接続できていないエラー。
  • (原因例)
    • .envファイルとMySQL(DB)の、DB_DATABASE、DB_USERNAME、DB_PASSWORDが異なる。
    • .envファイルの修正後、キャッシュをクリアできてない。
    • rootユーザーのPW変更後に、MySQLを再起動してない。
    • MySQLソケットに関するファイル(mysql.sock)が読み込まれてない。 → database.phpで unix_socket を設定する。
ターミナルからunix_socketを確認
// MySQL
% show variables like '%sock%';
            :
 | socket | /Applications/MAMP/tmp/mysql/mysql.sock |
unix_socketの設定(database.php)
'mysql' => [
  'driver'      => 'mysql',
  'host'        => 'localhost',
          : 
  'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock', 
],

■ カラム型 一覧

コマンド 概要
increments('id'); 符号なしの数値(INT)を使ったID(主キー)。0〜4294967295。
bigIncrements('id'); 符号なしのBIGINTを使ったID(主キー)。0〜18446744073709551615。※ 21億行以上にならないなら、↑ を使う。
tinyInteger('numbers'); 数値(TINYINT型)。1バイト
smallInteger('カラム名'); 数値(SMALLINT型)。2バイト
mediumInteger('カラム名'); 数値(MEDIUMINT型)。3バイト
integer('カラム名'); 数値(INT型)。4バイト
bigInteger('カラム名'); 数値(BIGINT型)。8バイト
float('カラム名', ○, △); トータルで8桁、小数点以下2桁以内の小数
double('カラム名', ○, △); トータルで15桁、小数点以下8桁以内の小数
decimal('カラム名', ○, △); トータルで5桁、小数点以下2桁以内の小数
char('カラム名', 5); 固定長文字列(長さが決まってる文字列)
string('カラム名'); 可変長文字列。デフォルトの最大文字数:255文字
string('カラム名', 100); 最大文字数指定の可変長文字列
text('カラム名'); 文字列。65,535文字(約64Kバイト)
mediumText('カラム名'); 長い文字列。16,777,215文字(約16Mバイト)
longText('カラム名'); めっちゃ長い文字列。4,294,967,295文字(約4Gバイト)
date('カラム名'); 日付
time('カラム名'); 時間
timeTz('カラム名'); 時間(タイムゾーン付き)
dateTime('カラム名'); 日時
dateTimeTz('カラム名'); 日時(タイムゾーン付き)
boolean('カラム名')->default(false); 真偽値
enum('カラム名', ['定数', '定数']); enum型
binary('カラム名'); バイナリデータ
json('カラム名'); JSON
jsonb('カラム名'); JSONB
timestamp('カラム名'); タイムスタンプ
timestampTz('カラム名'); タイムスタンプ(タイムゾーン付き)
timestamps(); created_atとupdated_at
nullableTimestamps(); ↑と同じ(NULLを許可)
softDeletes(); NULL可能な deleted_at カラム。例:退会日時などの管理用途(nullでなければ、退会済)
ipAddress('カラム名'); IPアドレス
macAddress('カラム名'); MACアドレス
rememberToken(); Eloquent認証ドライバーを扱うためのカラム。remember_tokenVARCHAR(100)NULLとして追加
uuid('id'); UUID。重複の可能性が小さく、一意な識別子として扱えるID
morphs('カラム名'); 符号なし数値(taggable_id)と文字列(taggable_type)を追加

■ オプション(カラム修飾子)一覧

カラム修飾子 概要
->comment('コメント内容') コメント追加(MySQLのみ)
->nullable() NULL許可
->unsigned() 整数カラムを符号なしに設定(MySQLのみ)。外部キーでよく使う
->default('値')、->default($value) デフォルト値を設定
->first() テーブルの最初(first)に設置(MySQLのみ)
->after('カラム名') 指定カラムの次にカラム追加(MySQLのみ)
->autoIncrement() 整数カラムをID(主キー)に設定
->charset('utf8') キャラクタセットを指定(MySQLのみ)
->collation('utf8_unicode_ci') コロケーションを指定(MySQL/SQL Serverのみ)
->nullable($value = true)、->nullable()->default(null) デフォルトでNULL値を指定
->storedAs($expression) stored generatedカラムを生成(MySQLのみ)
->useCurrent() TIMESTAMPカラムのデフォルト値をCURRENT_TIMESTAMPに指定
->virtualAs($expression) virtual generatedカラムを生成(MySQLのみ)

■ データの作成

  • テーブルが作成できたら、データを作成してみる。

seederで初期値を作成する場合

例)UsersTableSeeder.php生成
% php artisan make:seeder UsersTableSeeder        // UsersTableSeeder.phpが生成される
database/seeds/UsersTableSeeder.php
public function run(){
  DB::table('users')->insert([
    'name' => 'ユーザー1',
    'email' => 'ユーザー1@gmail.com',
    'password' => bcrypt('ユーザー1') 
  ]);
}
database/seeds/DatabaseSeeder.php
public function run()
{
  // $this->call(UsersTableSeeder::class);   // コメントアウトする
}
seederから、データを作成する
% php artisan db:seed --class=UsersTableSeeder     // データ作成
% php artisan tinker                               // 作成したデータの確認
  >>> use App\User
  >>> User::all()

コンソール操作でレコードを作成する場合

ターミナル操作で作成する方法
% php artisan tinker               // コンソール起動
  // レコード作成( インスタンスを作成して、saveメソッドを使う )
  >>> $box = new App\Box();        // インスタンス作成(※ 名前空間がデフォルトでAppなので、App\モデル名(); )
  >>> $box -> title = 'タイトル1';
  >>> $box -> content = '詳細1';
  >>> $box -> save();              // 保存
  => true                         // レコード作成成功

  >>> App\Box::all();             // 作成したデータの確認
  >>> App\Box::all()->ToArray();  // 作成したデータの確認(配列で取得)
  >>> exit
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel アウトプット

npm run watch-poll

npm run watch-pollは、Laravelをインストールした際に初めから存在するpackage.json内に定義されているコマンドのひとつです。

このコマンドは、各JavaScriptファイルを常に監視し、編集されたJavaScriptが保存されると自動的にLaravel Mixによるトランスパイルを行います。
JavaScriptの編集・保存の都度、手動でトランスパイルする必要が無くなり、開発を効率化します。
なお、npm run watch-pollを起動中のターミナルでは他のことはできませんので、何か他のコマンドを実行したい場合は別のターミナル画面を使うようにしてください。
また、npm run watch-pollを終了させる場合はcontrol + cを押してください。

clickLikeメソッド

スクリーンショット 2020-10-17 16.35.36.png
ユーザーが未ログインであれば警告のポップアップを出して、早期リターンでメソッドを終了させるようにしています。

passedValidationメソッド

フォームリクエストのバリデーションが成功した後に自動的に呼ばれるメソッドです。
バリデーション成功後に何か処理をしたければ、ここに処理を書きます。
スクリーンショット 2020-10-17 18.16.16.png

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

データ記述言語と配列の対応

基本的なこと

PHPにはデータの格納手段に配列(Array)というものがあります。配列については山ほど資料があるのでArray やりたいことで調べたらすぐに出てきます。それぐらいに汎用性に優れ、多くの場面で使用されています。
そんな配列データを、ファイルなどに保存する機会は少なくありません。
そんなとき、読み込んだ時に元の配列のデータと同じにするために、データ記述言語が存在します。
データ記述言語とは主にJSONYAMLなどのことです。データを指定の形式通りに記述し保存することで、その形式に従って読めば保存したデータを完全に得ることができます。

配列の構造について理解する

配列は同じ用途の複数の「値」を1つのグループとして扱うためにあります。しかし、その値をさらに分類しておきたい場合は、分類名を「キー」としてその中にデータを格納することがあります。
キーがある配列は特別に「連想配列」といいます。PHPでは連想配列と普通の配列を区別せずに、「Array」として扱います。

キー

キーは要素を並列する場合には省略します。その場合、処理上ではキーには0, 1, 2...と連番が付されます。
PHPでは、キーに使用できるのは整数(int)か文字列(string)のみです。それ以外をキーにすると、整数または文字列に変換(toString())して格納されます。この変換の処理によっては、キーを正しく区別できないことがあります。

値には、どんなオブジェクトも格納できます。ですが、JSONなどのテキストファイルに保存する際はこれもまた整数または文字列に変換されます。データ記述言語に保存する配列は、必ず整数と文字列で構成する必要があります。

値に配列を入れることができます。これを「多次元配列」といい、入れ子のようにデータを記述できます。

配列のサンプル

  • 一般的な配列(下記の2例は混ぜることもできる)
$array = ["key1" => "value1", "key2" => "value2", "key3" => "value3"];
// "key1" => "value1", "key2" => "value2", "key3" => "value3"

$array = ["value1", "value2", "value3"];
// 0 => "value1", 1 => "value2", 2 => "value3"
  • 多次元配列(書き方は一般的な配列と同じ。値にまた配列を入れているだけ)
$array = [
  "keyA" => [
    "key1" => "value1",
    "key2" => "value2"
  ],
  "keyB" => [
    "key1" => "value3",
    "key2" => "value4"
  ]
];

値の参照

作った配列から値にアクセスするには、配列[キー]と入力します。

$array = [
  "keyA" => [
    "key1" => "value1",
    "key2" => "value2"
  ],
  "keyB" => [
    "key1" => "value3",
    "key2" => "value4"
  ]
];

// $array["keyA"] は ["key1" => "value1", "key2" => "value2"]
// $array["keyB"]["key2"] は "value4"

データ記述言語の形式にする

前述のとおり、PHPは連想配列であるかを区別しないですが、主なデータ記述言語はそれらを区別するので、その点に気を使わなければいけません。
次のような例を使います。これは図書館の十進分類法を参考にしました。本を細かく分類するコードです。

分野名 コード 分類名 分野名 コード 分類名
産業 0 産業 言語 0 言語
産業 1 農業 言語 1 日本語
産業 2 園芸 言語 2 中国語・その他の東洋の諸言語
産業 3 蚕糸業 言語 3 英語
産業 4 畜産業・獣医学 言語 4 ドイツ語

上の表を配列にする1つの例です。

$bunrui = [
  "産業" => [
    "産業", "農業", "園芸", "蚕糸業", "畜産業・獣医学"
  ],
  "言語" => [
    "言語", "日本語", "中国語・その他の東洋の諸言語", "英語", "ドイツ語"
  ]
];

// $bunrui["産業"] は ["産業", "農業", "園芸", "蚕糸業", "畜産業・獣医学"]
// $bunrui["言語"][1] は "日本語"

$bunruiは連想配列です。しかし、$bunrui["産業"]$bunrui["言語"]は連想配列ではありません。

これをJSONとYAMLにそれぞれ変換してみましょう。結果は以下の通りです。

JSON

JSON
{
  "産業": [
    "産業",
    "農業",
    "園芸",
    "蚕糸業",
    "畜産業・獣医学"
  ],
  "言語": [
    "言語",
    "日本語",
    "中国語・その他の東洋の諸言語",
    "英語",
    "ドイツ語"
  ]
}

JSONでは、連想配列は{キー: 値}の形、その他配列は[値, 値, 値...]の形になります。

YAML

YAML
---
産業:
- 産業
- 農業
- 園芸
- 蚕糸業
- 畜産業・獣医学
言語:
- 言語
- 日本語
- 中国語・その他の東洋の諸言語
- 英語
- ドイツ語
...

YAMLでは、連想配列はキー: 値の形、その他配列は

- 
- 
- 
...

の形になります。YAMLは括弧がないので少しわかりにくいです。
ただし、ほとんどの文字列は"(クオーテーション)で囲まなくていいので、楽ではあります。

ということで

PHPの配列データをデータ記述言語に変換するフォーマットを、構造を説明しつつ解説してみました。
どういう場面に連想配列にするか、どういうデータの形式にするかをよく考えて作ってみてください。

さいごに

phpのリファレンス最強伝説を残しておきます。
php.netを見ろ!!!!!!!!!!!!!読め!!!!!!!!!!!!!!!!!!!!!!!

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

[PHP]データ記述言語と配列の対応

基本的なこと

PHPにはデータの格納手段に配列(Array)というものがあります。配列については山ほど資料があるのでArray やりたいことで調べたらすぐに出てきます。それぐらいに汎用性に優れ、多くの場面で使用されています。
そんな配列データを、ファイルなどに保存する機会は少なくありません。
そんなとき、読み込んだ時に元の配列のデータと同じにするために、データ記述言語が存在します。
データ記述言語とは主にJSONYAMLなどのことです。データを指定の形式通りに記述し保存することで、その形式に従って読めば保存したデータを完全に得ることができます。

配列の構造について理解する

配列は同じ用途の複数の「値」を1つのグループとして扱うためにあります。しかし、その値をさらに分類しておきたい場合は、分類名を「キー」としてその中にデータを格納することがあります。
キーがある配列は特別に「連想配列」といいます。PHPでは連想配列と普通の配列を区別せずに、「Array」として扱います。

キー

キーは要素を並列する場合には省略します。その場合、処理上ではキーには0, 1, 2...と連番が付されます。
PHPでは、キーに使用できるのは整数(int)か文字列(string)のみです。それ以外をキーにすると、整数または文字列に変換(toString())して格納されます。この変換の処理によっては、キーを正しく区別できないことがあります。

値には、どんなオブジェクトも格納できます。ですが、JSONなどのテキストファイルに保存する際はこれもまた整数または文字列に変換されます。データ記述言語に保存する配列は、必ず整数と文字列で構成する必要があります。

値に配列を入れることができます。これを「多次元配列」といい、入れ子のようにデータを記述できます。

配列のサンプル

  • 一般的な配列(下記の2例は混ぜることもできる)
$array = ["key1" => "value1", "key2" => "value2", "key3" => "value3"];
// "key1" => "value1", "key2" => "value2", "key3" => "value3"

$array = ["value1", "value2", "value3"];
// 0 => "value1", 1 => "value2", 2 => "value3"
  • 多次元配列(書き方は一般的な配列と同じ。値にまた配列を入れているだけ)
$array = [
  "keyA" => [
    "key1" => "value1",
    "key2" => "value2"
  ],
  "keyB" => [
    "key1" => "value3",
    "key2" => "value4"
  ]
];

値の参照

作った配列から値にアクセスするには、配列[キー]と入力します。

$array = [
  "keyA" => [
    "key1" => "value1",
    "key2" => "value2"
  ],
  "keyB" => [
    "key1" => "value3",
    "key2" => "value4"
  ]
];

// $array["keyA"] は ["key1" => "value1", "key2" => "value2"]
// $array["keyB"]["key2"] は "value4"

データ記述言語の形式にする

前述のとおり、PHPは連想配列であるかを区別しないですが、主なデータ記述言語はそれらを区別するので、その点に気を使わなければいけません。
次のような例を使います。これは図書館の十進分類法を参考にしました。本を細かく分類するコードです。

分野名 コード 分類名 分野名 コード 分類名
産業 0 産業 言語 0 言語
産業 1 農業 言語 1 日本語
産業 2 園芸 言語 2 中国語・その他の東洋の諸言語
産業 3 蚕糸業 言語 3 英語
産業 4 畜産業・獣医学 言語 4 ドイツ語

上の表を配列にする1つの例です。

$bunrui = [
  "産業" => [
    "産業", "農業", "園芸", "蚕糸業", "畜産業・獣医学"
  ],
  "言語" => [
    "言語", "日本語", "中国語・その他の東洋の諸言語", "英語", "ドイツ語"
  ]
];

// $bunrui["産業"] は ["産業", "農業", "園芸", "蚕糸業", "畜産業・獣医学"]
// $bunrui["言語"][1] は "日本語"

$bunruiは連想配列です。しかし、$bunrui["産業"]$bunrui["言語"]は連想配列ではありません。

これをJSONとYAMLにそれぞれ変換してみましょう。結果は以下の通りです。

JSON

JSON
{
  "産業": [
    "産業",
    "農業",
    "園芸",
    "蚕糸業",
    "畜産業・獣医学"
  ],
  "言語": [
    "言語",
    "日本語",
    "中国語・その他の東洋の諸言語",
    "英語",
    "ドイツ語"
  ]
}

JSONでは、連想配列は{キー: 値}の形、その他配列は[値, 値, 値...]の形になります。

YAML

YAML
---
産業:
- 産業
- 農業
- 園芸
- 蚕糸業
- 畜産業・獣医学
言語:
- 言語
- 日本語
- 中国語・その他の東洋の諸言語
- 英語
- ドイツ語
...

YAMLでは、連想配列はキー: 値の形、その他配列は

- 
- 
- 

の形になります。YAMLは括弧がないので少しわかりにくいです。
ただし、ほとんどの文字列は"(クオーテーション)で囲まなくていいので、楽ではあります。

ということで

PHPの配列データをデータ記述言語に変換するフォーマットを、構造を説明しつつ解説してみました。
どういう場面に連想配列にするか、どういうデータの形式にするかをよく考えて作ってみてください。

さいごに

phpのリファレンス最強伝説を残しておきます。
php.netを見ろ!!!!!!!!!!!!!読むんだ今すぐ!!!!!!!!!!!!!!!!!!!!!!!

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

testareaの初期値(Value)が反映されない時の解決法

エラー状況

例えば下記のような入力フォームにinputエリアとtextareaエリアを実装したとする。

Todo

更新して再度開いた時に前回、更新した内容が表示できるようにしたい。
しかしinputエリアは通常に表示されているが、textareaは表示がされていない状況。

Todo

修正作業

コードを確認してみると

<div class="title-area">
  <label for="test1">タイトル</label>
  <input id="test1" type="text" name="title" value="{{$sample->title}}">
</div>
<div class="text-area">
  <label for="test2">メモ</label>
  <textarea id="test2" type="text" name="memo" value="{{$sample->memo}}" row="5"></textarea>
</div>

一見、問題ないように見えますが、
textareaにvalueを設定するのではなく、開始タグと閉じタグの間に表示されたい変数などを入れるようにコードを修正すれば、表示されると思います。

<div class="title-area">
  <label for="test1">タイトル</label>
  <input id="test1" type="text" name="title" value="{{$sample->title}}">
</div>
<div class="text-area">
  <label for="test2">メモ</label>
  <textarea id="test2" type="text" name="memo" row="5">{{$sample->memo}}</textarea>
</div>

最後に

textareaはinputと同じように書きがちなので初学者の方がハマるエラーだと思い、執筆しました。
参考になれば幸いです。

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

Moodle 3.9 マニュアル - コースリスト

原文

内容

1 掲載されているコースの順番
2 コース連絡先
3 拡張コース名の表示
4 ページあたりのコース
5 サマリー制限のあるコース
6 コース要約ファイルの制限とコース要約ファイルの拡張子
7 関連項目

1 掲載されているコースの順番

フロントページに表示されるコースの順番は、管理者が管理 > サイト管理 > コース > コースとカテゴリの管理で設定することができます。

2 コース連絡先

管理者は、管理 > サイト管理 > 外観 > コースで、コースの連絡先として表示されるユーザーを変更することができます。

選択された役割を持つユーザー(例:教師)は、コースの説明に表示されます。

Course_list.png
コース一覧.png

デフォルトでは、コースの教師の役割を持つユーザーはそのコースのコース説明にリストされます。コースに複数の教師がいる場合、コースの説明がかなり長くなることがあります。このような場合、例えば、能力が設定されていない科目担当者などのロールを作成し、教師ロールに加えて選択したユーザーに割り当てることができます。この場合、コースマネージャー設定で科目担当者ロールのみを選択すると、コースの説明は短くなります。注: コースに登録されているユーザーのみがコースの連絡先として表示されます。

コースで自己登録が使用されている場合、コース連絡先の役割を持つユーザーからウェルカムメッセージのメールが送信されることがあります。役割を持つユーザーが複数いる場合は、コース連絡先の役割を持つ最初のユーザーからウェルカムメッセージが送信されます。

3 拡張コース名の表示

デフォルトでは、コース一覧にはコースのフルネームのみが表示されます。このボックスをチェックすると、コースの短縮名も表示されます。これを有効にすると、言語のカスタマイズを使用して文言を編集することもできます。詳細については、フォーラムのディスカッションコースの拡張名表示言語の変更を参照してください。

4 ページあたりのコース

ここでは、コース一覧でページごとに表示するコースの数を選択することができます。

5 サマリー制限のあるコース

コースが一覧表示されている場合は、全コースの概要が表示されます。サマリーの表示は非常に便利ですが、ページが非常に長くなってしまいます。多数のコースがある場合、クリックして詳細情報 (つまり完全な要約) に移動できるアイコンを表示する方が良いかもしれません。ここでは、Moodleが「詳細情報」アイコンに戻る前に完全な要約を表示するコースの数を決めることができます。

6 コース要約ファイルの制限とコース要約ファイルの拡張子

コース管理者はコースにファイルを追加することができます。これらのファイルはコース名および/またはコース概要と同様に、コースの外部から誰でもアクセスすることができます。moodle/course:changesummaryケイパビリティを持つユーザのみがコース概要ファイルをアップロード/変更することができます。デフォルトでは、コース管理者は最大1つの画像ファイルをコースに追加することができるように設定されています。テーマはそれらのファイルがコースリストにどのように表示されるかを決定します。

7 関連項目

コース

カテゴリ サイト管理 コース

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

zendコンテナページのzendコンテナの内容が、ドキュメントと食い違う

たぶん7系でzendコンテナの実装が変更になったことによるもの。

https://hnw.hatenablog.com/entry/20141207

$ php -r "var_dump(phpversion('xdebug'));"
Command line code:1:
string(9) "2.9.7-dev"

https://www.php.net/manual/ja/features.gc.refcounting-basics.php

a: (refcount=2, is_ref=0)='new string'
a: (interned, is_ref=0)='new string'

Xdebugの仕様とのことです。
文字列の場合、refcountの出力が抑制されるようになっているとのこと。

https://stackoverflow.com/questions/56833897/why-increasing-refcount-of-zval-not-working

上記リンク先において紹介されていた,該当箇所の変更
https://github.com/xdebug/xdebug/commit/dd3c9b4127778dccbf61b98746797c7b88a4caf7

参考

Xdebugのバージョンを確認する方法
https://stackoverflow.com/questions/2479394/how-to-know-the-xdebug-version-i-have-installed

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

PHPマニュアル「参照カウント法の原理」ページのサンプルコード出力が,マニュアル記載のものと異なる

発生した問題

マニュアルと,手元のコードの実行結果が食い違う

以下のコードです.
https://www.php.net/manual/ja/features.gc.refcounting-basics.php

<?php
$a = "new string";
xdebug_debug_zval('a');
?>

マニュアル記載の出力は以下のようになります.

a: (refcount=2, is_ref=0)='new string'

実際の出力は以下のようになります.

a: (interned, is_ref=0)='new string'

refcountの数値の変動を確認したいのに,これでは困ります.

原因

Xdebugのバージョンアップに伴う仕様変更とのことです.
手元のXdebugのバージョンを確認すると,"2.9.7-dev" でした.

$ php -r "var_dump(phpversion('xdebug'));"
Command line code:1:
string(9) "2.9.7-dev"

下記の変更において,文字列の場合,refcountの出力が抑制されるようになったようです.
https://github.com/xdebug/xdebug/commit/dd3c9b4127778dccbf61b98746797c7b88a4caf7

リンク発見元:https://stackoverflow.com/questions/56833897/why-increasing-refcount-of-zval-not-working

これはまだよく理解できていない状態での推測なのですが,おそらく,7系でzendコンテナの実装が変更になったことによるものではないかなと思っています.

https://hnw.hatenablog.com/entry/20141207

参考

Xdebugのバージョンを確認する方法
https://stackoverflow.com/questions/2479394/how-to-know-the-xdebug-version-i-have-installed

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

Moodle 3.9 マニュアル - ユーザーの追加

原文

ユーザは多くの方法でMoodleサイトに追加することができます。ユーザアカウントがサイト上に作成された場合、このプロセスは認証と呼ばれ、ユーザがコースに参加する場合、このプロセスは登録と呼ばれます。通常、管理者のみがユーザをサイトに追加することができます。コースの教師はコースに学生を追加することしかできず、サイトにユーザーを追加する権限はありません。(あなたが教師で、コースに学生を追加する方法をお探しの場合は、学生を追加するお読みください)

ユーザーが自分でサイトにサインアップします。

あなたのサイトに独自のアカウントを作成したい場合は、電子メールベースの自己登録を有効にする必要があります。スパマーがあなたのサイトにアクセスする可能性があるため、この機能はデフォルトで無効になっています。

500px-selfregscreen.png
アカウントにサインアップする

管理者が手動でアカウントを作成する

この処理は手動認証と呼ばれ、サイトではデフォルトで有効になっています。サイト管理 > プラグイン > 認証 > 手動アカウントから、特定のフィールドをロックしたり、パスワードの有効期限を設定したり、その他の設定を行うことができます。

管理者として、サイト管理 > ユーザー > アカウント > 新しいユーザーの追加 から、ユーザーを 1 人ずつ追加することができます。詳細については、ドキュメント新しいユーザーの追加を参照してください。

また、「サイト管理」 > 「ユーザー」 > 「アカウント」 > 「ユーザーをアップロード」から、CSV ファイルを使用してユーザーを一括でアップロードすることもできます。詳細については、ユーザーをアップロードするを参照してください。

また、CSV ファイルは、コースとそのコース内のグループに直接ユーザーをアップロードします。以下の例では、新しい学生がサイトに追加され、英語と数学の2つのコースの指定されたグループに登録されています。(コースはすでに存在している必要がありますが、グループがまだ存在しない場合、Moodleはアップロード時にグループを作成します)

500px-uploaduserscsvexample.png
新しいユーザがサイト、コースおよびグループに追加されます

ユーザーは、コホート (サイトまたはカテゴリ全体のユーザーのバッチ) のメンバーとして追加することもできます。詳細については、コホートを参照してください。

他のシステムからユーザーを追加する

ユーザが他のシステムからシングルサインオンでMoodleに接続することが可能です。これらの設定は、サイト管理 > プラグイン > 認証 > 認証の管理で見つけることができます。

CASサーバ (SSO) - アカウントの詳細は外部CASサーバにあります。
外部データベース - アカウントの詳細は外部データベースにあります。
LDAPサーバー - アカウントの詳細は外部のLDAPサーバーにあります。
Moodleネットワーク認証 - 異なるMoodleサイトがどのようにユーザを接続し、認証するか。
Shibboleth - アカウントの詳細は外部のShibbolethサーバーにあります。
・ウェブサービス認証

カテゴリ サイト管理

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

staticキーワードをつけた関数内定義変数をunsetするとどうなるか

結構面白い挙動になりました.

<?php

function func()
{
    static $x = 0;
    $x++;
    echo $x;
    unset($x);
    echo $x;
}

func();
func();
func();

https://3v4l.org/tQLiW

image.png

4行目で static で宣言された $xくんは,8行目で unset() され,9行目で確かに未定義の状態となったことが確認できますが,次の関数呼び出しの際には元の値を保持したまま復活します.

面白いなと思ってPHPのマニュアルを見てみたら,マニュアルで紹介されている挙動でした (┐「ε:)ズコ-!

If a static variable is unset() inside of a function, unset() destroys the variable only in the context of the rest of a function. Following calls will restore the previous value of a variable.

destroyされたあと,restoreされるらしいです.すごいですね.

余談

staticキーワードを無駄に使ってメモリを無駄遣いするコードです.

<?php

function func()
{
    static $x;
    if (!isset($x)) {
        $x = 'func';
    }
    echo $x;
}

func();
func();
func();

https://3v4l.org/LuNhY

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

PHP+MySQLで作成したアプリをHerokuでデプロイする手順(workbenchの設定まで)

概要

初心者がPHPで作成したwebアプリをHerokuでデプロイするまでの過程をまとめてみました。

環境

 【言語】: HTML、CSS(レスポンジブ未対応)、PHP 7.3.9、JavaScript、jQuery2.2.2
 【DBMS】: MySQL 5.7.26
 【フレームワーク】: なし
 【開発環境】: MacOS Catalina 10.15.5
 【バージョン管理】: Git 2.24.3
 【本番環境】: Heroku

大まかな流れ

1.Gitと連携

2.Heroku操作

3.DB情報の移行(workbench操作)

4.ライブラリの追加

5.Herokuへpush

1.Gitと連携

※既にGithubにリポジトリを作成している場合はの過程はスキップ

①新規リモートリポジトリを作成

②デプロイするディレクトリに移動し、ローカルリポジトリの作成↓

$ git init

③add~push↓

$ git add.
$ git commit -m 'commit'
$ git push origin master

2.Heroku操作

①Herokuにログイン↓(Herokuのインストールの説明は省略)

$heroku login

②Heroku上に新しくアプリケーションを作成↓

$ heroku create つけたいアプリ名
 Warning: heroku update available from 7.35.0 to 7.44.0.
Creating ⬢ つけたいアプリ名... done
https://munakatatest8.herokuapp.com/ | https://git.heroku.com/munakatatest8.git

③HerokuのアプリケーションにClearDBを追加↓(igniteは無料です)

$ heroku addons:create cleardb:ignite
Creating cleardb:ignite on ⬢ つけたいアプリ名... free
Created cleardb-rectangular-89660 as CLEARDB_PUCE_URL
Use heroku addons:docs cleardb to view documentation

④データベース情報の確認↓(後々この情報を使用します)

$ heroku config | grep CLEARDB_DATABASE_URL

CLEARDB_DATABASE_URL: mysql://******:******@us-cdbr-east-02.cleardb.com/heroku_dff14ec3ad68e70?reconnect=true
//↓下記のデータが入ってる認識
CLEARDB_DATABASE_URL: mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true

3.DB情報の移行(workbench操作)

①Workbenchのインストール
MySQL Workbenchの公式ページに飛んで、「ダウンロードはこちら」をクリック。

②インストールが完了したら、phpmyadmin から使用したいDBをエクスポート↓
スクリーンショット 2020-10-05 20.03.40.png

③workbenchを起動し、Connectionを新規作成↓
2-④で取得したCLEARDBのユーザー名、ホスト名、データベース名、パスワードを打ち込む
スクリーンショット 2020-10-05 20.17.15.png

『Test Connection』を実行したところ謎のwarningが表示されたが、無視して続行。↓

スクリーンショット 2020-10-05 20.16.57.png

パスワードを再度打ち込み→any continueと進み
『MySQL接続が正常に確立されました』との表示がでたため、↓
スクリーンショット 2020-10-05 20.23.15.png

戻って立ち上げたconectionをクリック
④DB情報をインポート
Data Import/Restoreをクリックしインポート画面へ。

エクスポートした、DB情報ファイルを入力、
スクリーンショット 2020-10-17 13.04.25.png

【記入箇所】
・Import from Self-Contained→Fileを選び、エクスポートした「〇〇〇〇.sql」を記入。

・Default Target Schema→Newではなくデフォルトで表示されるデータベース名を選択。

・Start Importを押してインポート。

Import Completedと表示されレバ、インポートが完了し、Workbenchのデータベース設定も無事終了。

⑤エラー例
私がDB情報のインポートの際実際に直面したエラーです。
スクリーンショット 2020-10-05 22.23.16.png
スクリーンショット 2020-10-05 20.41.45.png

原因

SQL文内に「CREATE DATABASE IF NOT EXISTS」が含まれていた。
ここではデータベースが1つしか使えない設定になっている為エラーが起きた。

解決法

1.エクスポートしたSQLファイルをメモ帳などのエディタで開く
2.CREATE DATABASE IF NOT EXISTSで始まる1行を削除
2.その下にUSE ‘データベース名’があればそれも削除

Import Completedと表示されたため、 DBのインポート完了

⑥自分が作ったwebアプリをデータベースに接続できるようするためコードを書き換える。

function dbConnect()
{

  $dsn = 'mysql:dbname=DB名;host=ホスト名;charset=utf8';
  $user = 'ユーザー名';
  $password = 'パスワード';
  $option = array(

    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
  );

  $dbh = new PDO($dsn, $user, $password, $option);
  return $dbh;
}

⑦完了したら、git add~pushまで行う

4.ライブラリの追加

デプロイする前にフォルダの中に「composer.json」「composer.lock」「Procfile」がきちんと入っているか確認する。

もし入っていない場合は、フォルダ内にこれらのファイルを追加する。

①ディレクトリ内にcomposerのインストール

brew install composer

②ディレクトリにcomposer.jsonファイルが追加されているので中身にPHPのバージョンを記述

{
  "require": {
    "php": "~7.3.9",
    "ext-mbstring": "*"
  }
}

③次にcomposer.lockファイルの追加

composer install

vendorディレクトリ、composer.lockファイルが追加されていることを確認。

スクリーンショット 2020-10-17 13.27.28.png

↑追加されている状態

5.Herokuへpush

①フォルダの中身を確認し「composer.json」「composer.lock」が存在していれば、ターミナルに下記を打ち込む。

$ git push heroku master

エラーメッセージが出なければ、無事にデプロイ完了。

②実際にページを開いて確認

$ heroku open

アプリが表示されていればデプロイ完了。

デプロイ後私が経験したエラー

・DBのカラム形式が間違っている(invaild~)
・小文字大文字が混同してる。(404)

最後に

以上、Herokuを使って、PHPポートフォリオサイトを無料でデプロイする方法でした。認識違いなどございましたら、ご指摘していただけると幸いです。

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

【PHP】今日、Laravel始めました

ビルトインサーバーでのLaravel導入についての備忘録。
MacのPHPバージョンアップ、Laravel導入、DB(MySQL)への接続まで。

環境構築(Mac)

  • 現在のPHPの最新バージョン 7.4に、Homebrewを使って、バージョンアップ。
PHPのバージョンアップ
% php -v                      // Macに入ってるバージョン確認
  PHP 7.3.11 ...
% brew search php@7           // Homebrewコマンドで、インストールができるPHP7系を検索してみる
  => Formulae
  php@7.2       php@7.3       php@7.4
% brew install php@7.4        // Homebrewを使って、7.4 をインストール
  Updating Homebrew...
         :

// インストールが完了したら、PATHを通す設定を上書きする
% echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.bash_profile
% echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.bash_profile
% source ~/.bash_profile

% brew services start php       // PHPを起動
// ターミナルを一旦閉じてから、バージョン確認してみる
% php -v
  PHP 7.4.11 ...
  • Laravel導入には、以下が必要なのでインストールする。
    • Homebrew : 導入済み
    • PHP : 導入済み
    • Composer : ライブラリやパッケージを管理し、それをもとにインストールする機能。
    • Laravel
Laravelの導入まで
// Composer インストール
% brew search composer
  ==> Formulae
  composer
  ==> Casks
  composercat
% brew install composer
% composer -v                  // 導入を確認
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
  Composer version 1.10.6 2020-05-06 10:28:10
          :
// Laravelのインストール
% composer global require "laravel/installer"
// Laravelのコマンドを使えるようにするために、パスを通す(.zshrcファイル)
% vim ~/.zshrc                // i(挿入モード)で編集し、escキーで抜け、:wqで保存して終了
  export PATH="$PATH:/Users/自分のPC名/.composer/vendor/bin"
% source ~/.zshrc            // 変更を反映
% laravel -v                 // 導入を確認
  Laravel Installer 4.0.5
          :

Laravelアプリ作成の実装手順

アプリの雛形作成

  • artisan(アーティサン)コマンド : Laravelの機能を呼び出すコマンド。
Laravelアプリの作成
% cd ~/projects
% laravel new laravel_sample    // アプリ名 「 laravel_sample 」
% cd sample
% php artisan serve             // サーバーを起動し、ブラウザで確認(localhost:8000)
                                // サーバー停止は、 control + C
  • localhost:8000 にアクセス↓(※ app/resources/views/welcome.blade.php が表示されてればOK) Alt text

laravelアプリのディレクトリ構造

ざっくりしたディレクトリ構造
・app
  └─ Http  
       └─ コントローラー     
  └─ モデル
・database
    └─ マイグレーション
・resources
    └─ ビュー
・routes
    └─ web.php (ルーティング)

タイムゾーンと言語だけ設定しとく

  • レコード保存時の時間情報の設定など。
タイムゾーンと言語の設定(config\app.php)
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'faker_locale' => 'ja_JP',

DB作成(mySQL)

  • DB接続には、 ホスト、ポート、DB名、ユーザー名、PW が必要。
  • Laravelでは、.envファイルに、環境変数を記載。多分、デフォルトのままでok。

DB作成のための設定

アプリ作成時に作成された.envファイル(DB関連部分)
        :
DB_CONNECTION=mysql         // DBの種類
DB_HOST=127.0.0.1           // 接続先のホスト
DB_PORT=3306                // 接続先のポート
DB_DATABASE=laravel_sample  // DB名
DB_USERNAME=root            // ユーザー名
DB_PASSWORD=                // PW(なくてok)
        :
config/database.php
'mysql' => [
                 :
  'database' => env('DB_DATABASE', 'laravel_sample'),
  'username' => env('DB_USERNAME', 'root'),
  'password' => env('DB_PASSWORD', ''),
                 :

DB作成

  • MySQLにrootでログインし、DBを作成する。
ターミナル
% mysql -u root                            // rootでMySQLにログイン
  mysql> create database laravel_sample;   // DB作成
    Query OK, 1 row affected (0.01 sec)
  mysql> show databases;                   // DB一覧で確認
  mysql> exit

DBをアプリと接続する

アプリのディレクトリ(ターミナル)
% php artisan tinker                              // 対話コマンド
  Psy Shell v0.10.4 (PHP 7.4.11 — cli) by Justin Hileman
  >>> DB::connection();                           // DBが接続されてるか確認
  => Illuminate\Database\MySqlConnection {#3238}
  >>> exit                                        // 確認できたら終了しとく
% php artisan migrate                             // マイグレーション実行
  • これで、MySQLと繋がり、空のDBが作成できたハズ。

よく使いそうな Laravel artisanコマンド

よく使いそうなコマンド
% php artisan --version             // バージョンの確認

% php artisan                      // コマンド一覧の確認方法 (引数の使い方も確認できるみたい)
% php artisan list
% php artisan make:model -h        // モデル作成に、どんなオプションがあるか?
% php artisan make:controller -h   // コントローラー作成に、どんなオプションがあるか?

% php artisan serve                // ローカルサーバー起動(8000)
% php artisan route:list           // ルーティングの確認
% php artisan tinker               // 対話コンソールの起動
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Moodle 3.9 マニュアル - カテゴリ:サイト管理

原文

カテゴリ:サイト管理

サイト管理設定に関する情報を含むドキュメントページのインデックス。
サブカテゴリ

このカテゴリには、合計2つのサブカテゴリのうち、以下の2つのカテゴリがあります。

Accounts

S

Security

カテゴリ「サイト管理」のページ

全219ページのうち、次の200ページがこのカテゴリのものです。

コースブロック
コースリスト

ユーザーの追加
ユーザーをアップロードする

A

Accounts FAQ
ad-hoc contributed reports
Add a new user
Add users (日本語訳:ユーザーの追加)
Additional name fields
Admin quick guide
Admin tools
admin/environment/custom check/unsupported db table row format
admin/environment/database/mssql
admin/environment/database/mysql
admin/environment/database/mysql (5.5.36)
admin/environment/moodle
admin/environment/pcreunicode
admin/environment/php
admin/environment/php extension/ctype
admin/environment/php extension/curl
admin/environment/php extension/dom
admin/environment/php extension/gd
admin/environment/php extension/hash
admin/environment/php extension/iconv
admin/environment/php extension/intl
admin/environment/php extension/json
admin/environment/php extension/mbstring
admin/environment/php extension/openssl
admin/environment/php extension/pcre
admin/environment/php extension/simplexml
admin/environment/php extension/soap
admin/environment/php extension/spl
admin/environment/php extension/tokenizer
admin/environment/php extension/xml
admin/environment/php extension/xmlreader
admin/environment/php extension/xmlrpc
admin/environment/php extension/zip
admin/environment/php extension/zlib
admin/environment/php setting/file uploads
admin/environment/php setting/memory limit
admin/environment/php setting/safe mode
Adminer
Administration FAQ
Advanced features
AJAX and Javascript settings
Alfresco repository
Amazon S3 repository
Antivirus plugins
Authentication
Automated course backup
Available update notifications

B

Backup
Blog settings
Box portfolio
Box repository
Box.net portfolio
Browse list of users
Bulk user actions

C

Calendar settings
Capabilities/moodle/cohort:assign
Capabilities/moodle/cohort:manage
Capabilities/moodle/cohort:view
Capabilities/moodle/site:config
Capabilities/moodle/site:configview
Capabilities/moodle/site:maintenanceaccess
Capabilities/moodle/user:viewlastip
Cleanup
Cohorts
Comments
Comments block
Community hubs
Config changes report
Content bank repository
Convert URLs into links filter
Course completion settings
Course list (日本語訳:コースリスト)
Course overview report
Courses block (日本語:コースブロック)
Creating custom roles
CSV
Custom SQL queries report

D

Dashboard
Database auto-linking filter
Database settings
Database transfer
Debugging
Developer tools
Display emoticons as images filter
Dropbox repository

E

Edit profile
Embedded files repository
Emoticon images
Enrolments
Environment
EQUELLA repository
Errors FAQ
Events list report
Experimental settings

F

File system repository
File system repository FAQ
Flickr public repository
Flickr repository
Front page
Front page settings

G

Glossary auto-linking filter
Glossary settings
Google Drive portfolio
Google Drive repository

H

Hacked site recovery
Header and footer
Health center
HTTP
HTTP security
HTTPS conversion tool

I

IP blocker

J

JMeter test plan generator

L

Language
Legacy course files
local/sanitychecker/view
Location
Logging
Logos
Logs

M

Mahara portfolio
Mail configuration
Maintenance mode
Managing a Moodle site
Managing accounts
Managing activities
Managing blocks
Managing local plugins
Managing plagiarism prevention
Managing questions
Managing reports
Managing repositories
Managing roles
MathJax filter
Media embedding
Merlot.org repository
Migration from MyISAM to InnoDB
Moodle version
More features
Multimedia plugins filter
MySQL full unicode support

N

Navigation
Nextcloud repository

O

OAuth 2 Facebook service
OAuth 2 Google service
OAuth 2 LinkedIn service
OAuth 2 Microsoft service
OAuth 2 Nextcloud service
OAuth 2 services
OAuth 2 Twitter service
OneDrive repository
Online users block
Oohoo - Capture repository
OPcache

P

Password salting
Performance
Picasa web album repository
Plagiarism prevention
Privacy
Private files

Q

Question behaviours
Question instances report

R

Recent activity block
Recent files repository
Reducing spam in Moodle
Remote RSS feeds block
Reports FAQ
Repositories FAQ
Role export and import
Roles and permissions
RSS feeds settings

S

Scheduled tasks
Search and replace tool
Section links block
Security
Security FAQ
Security overview report
Security recommendations
Server files repository
Server settings
Session handling
Sessions FAQ
Site appearance
Site notifications
Site registration
Site security settings
Site-wide reports
SSL certificate for moodle.org
Standard roles
Statistics
Sunsetting moodle.net
System paths
System status report

T

Tag settings
Tags block
Template library
Test course generator
TeX notation filter
Text editor
Themes
Transitioning to HTTPS

U

Unenrolment
Universal Office Converter (unoconv)
Upload a file repository
Upload cohorts
Upload users (日本語訳:ユーザーをアップロードする)

URL downloader repository
User pictures
User policies
User profile fields
User profiles
User tours
Using slash arguments

V

View profile

W

Web services
Web services test client
WebDAV repository
Wikimedia repository
Word censorship filter

Y

YouTube videos repository

メインページ

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

LaravelのアプリをLaravelのバージョンを指定して作成する

目的

  • Laravelアプリを作成する最にバージョンを指定して作成する方法をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.8 Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする
Laravel バージョン 8.6.0 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

方法

  1. Laravelアプリを作成したい環境で下記コマンドを実行する。コマンドは二通り存在する。

    • その1

      $ composer create-project "laravel/laravel=バージョン" アプリ名
      
    • その2

      $ composer create-project --prefer-dist laravel/laravel アプリ名 "バージョン"
      
  2. 例えばLaravel6の最も新しいバージョンで作成したいときは下記のようにして実行する。

    • その1

      $ composer create-project "laravel/laravel=6.*" アプリ名
      
    • その2

      $ composer create-project --prefer-dist laravel/laravel アプリ名 "6.*"
      
  3. Authによる認証機能をもたせたい場合はアプリファイル作成後アプリ名ディレクトリに移動して下記コマンドを実行し認証に必要なファイルを作成する。

    $ composer require laravel/ui "^1.0" --dev
    $ php artisan ui vue --auth
    
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Moodle 3.9 マニュアル - コースのバックアップ

原文

コースのバックアップを使用することで、コースの一部または全部を保存することができます。通常、サイト管理者はサイト全体の自動コースバックアップのスケジュールを設定します。教師は安全に保存するため、または他のMoodleサイトで使用するために、バックアップを作成するか、既存のバックアップをダウンロードすることができます。

video
コースのバックアップ。Moodle 3.7

内容

1 コースをバックアップするには
2 ユーザー情報の匿名化
3 非同期コースバックアップ
4 管理者のためのCLI経由のバックアップ
4.1 オプション
4.2 例
5 ヒントとコツ
6 クリエイティブな使用法
7 一般的なバックアップのデフォルト
8 コースのバックアップが90%を超えて停止し、エラーが表示されない
9 コースのバックアップのケイパビリティ
10 エラーが発生しました。バックアップファイルからユーザー 'admin' を復元しようとすると競合が発生します。
11 関連項目

コースのバックアップ

1 コースをバックアップするには

コースに入ります。
ギアメニューまたは管理ブロック(テーマによって異なります)の中のバックアップリンクをクリックします。
初期設定 - 必要に応じてアクティビティ、ブロック、フィルター、その他の項目を選択し、次へボタンをクリックします。管理者や管理者などの適切な権限を持つユーザーは、ユーザーを含めるか、ユーザー情報を匿名化するか、またはユーザーロールの割り当て、グループ、グループ化、ユーザーファイル、コメント、ユーザー完了の詳細、コースログ、成績履歴をバックアップに含めるかを選択することができます。
スキーマ設定 - バックアップに含める特定の項目を選択/選択解除し、[次へ]ボタンをクリックします。
必要に応じて、リンク「タイプオプションを表示」をクリックして、バックアップするアクティビティの特定のタイプを選択します。
確認とレビュー - 必要に応じて前のボタンを使用して、すべてが必要なものであることを確認します。
完了 - [続行]ボタンをクリックします。

バックアップ設定

すべてまたはなしを選択できるオプション付きのバックアップ画面

アクティビティの種類を選択できるオプション付きのバックアップ画面

バックアップファイル (zipファイルとの混同を避けるため、.mbz拡張子を持つ) はコースバックアップエリアに保存されます。バックアップファイル名はbackup-moodle2-course-coursename-date-hour.mbzの形式で、ユーザーなしでバックアップされた場合は-nu.mbzで終わり、匿名化された名前の場合は-an.mbzで終わります。

ヒント: あなたがデフォルト設定に満足していて、すべてのバックアップ画面を通過したくない場合、単に「最終ステップにジャンプ」をクリックしてバックアップを実行することができます。

2 ユーザー情報の匿名化

ユーザ情報の匿名化は、各ユーザを匿名にすることで「ユーザのアイデンティティを保護する」バックアップ機能です。バックアップの初期設定でこのボックスがチェックされている場合、Moodleは@doesntexist.comメールアドレスなどを実名の代わりにエイリアスで代用します。例えば、「Max Manager」は「anonfirstname4 anonlastname4」になるかもしれません。

3 非同期コースバックアップ

注意: 大規模なコースでは、コースのバックアップが行われている間に作業を続けることができると便利です。これを実現するには、サイト管理/コース/バックアップ/非同期バックアップ/リストアで非同期バックアップを有効にする必要があります。

4 管理者のためのCLI経由のバックアップ

サイト管理者は、CLI スクリプトを使用して選択したコースをバックアップすることができます。

4.1 オプション

    --courseid=INTEGER (バックアップ用のコースID)
    --courseshortname=STRING (バックアップ用のコースの短縮名)
    --destination=STRING (バックアップファイルを保存するパス。設定されていない場合、バックアップはコースのバックアップファイル領域に保存されます)
    -h, --help (このヘルプを印刷します。)

4.2例

\$sudo -u www-data /usr/bin/php admin/cli/backup.php --courseid=2 --destination=/moodle/backup/.php --courseid=2 --destination=/moodle/backup/.php

Windowsでは、/admin/cli/backup.phpスクリプトを実行するためにcmd.exeを使用します。あなたのMoodledataフォルダが別のデータサーバ上に設定されている場合、そのデータサーバ上のバックアップフォルダへのUNCパスを指定することができます。コマンドラインCDからMoodle \admin\cliフォルダに移動し、このコマンドを実行してください。

php backup.php --courseid=25 --destination=\moodledatabackup

ここで、'--courseid'はバックアップしたいコースのIDです。

courseid=25の.mbzバックアップファイルはMoodledata ($CFG->dataroot)フォルダ内のバックアップサブフォルダに保存されます。

5 ヒントとコツ

Moodle 2.0でリストア後にコンテンツが失われますか? トピックの見出しに「Orphaned activities」と表示されていますか? 解決方法を教えてください。コース設定に移動し、トピックセクションの数を増やしてください。

6 クリエイティブな使用法

バックアップとリストアのプロセスは、教師と管理者に多くの創造的なソリューションを提供することができます。

あるコースのコースや特定のアクティビティを別のコースに複製する (インポートに似ています)
ローカルホストサイトコースからの素材を使用して、プロダクションMoodleサイトコースを更新する
新しいMoodleサイトへのコースの転送。
以前のバージョンのMoodleでは、過去の学生の活動なしにコースを前に進める方法として
空白のアクティビティを作成し、そのアクティビティだけを保存し、コースまたは別のコースに1回以上リストアします。

7 一般的なバックアップのデフォルト

コースバックアップのデフォルト設定は、サイト管理者がサイト管理の「一般的なバックアップのデフォルト」で設定することができます。

選択した設定は、コースのバックアップを作成する際に変更できないようにロックすることができます。

Keep logs for...」ドロップダウンで時間を選択することで、バックアップログ情報が削除されるまでの期間を指定することができます。情報量が多い場合がありますので、選択した時間はかなり短くすることをお勧めします。

8 コースのバックアップが90%を超えて停止しエラーが表示されない

これが原因であることが報告されています。

非標準のコースフォーマット。コースフォーマットを置き換えてみてください。
サーバーのRAMが十分でない。通常、サーバーにRAMを追加することは、パフォーマンスを向上させるための最初の推奨事項](https://docs.moodle.org/39/en/Performance_recommendations)です。

9 コースのバックアップのケイパビリティ

バックアップ時のユーザーデータの匿名化
バックアップコース
バックアップセクション
インポートのためのバックアップ
バックアップオプションの設定
バックアップ領域からファイルをダウンロード
ユーザーデータのバックアップ

10 エラーが発生しました。バックアップファイルからユーザー'admin'を復元しようとすると、競合が発生します

・先に進む前に、何か問題が起こった場合に備えて、2つ目の管理者アカウントを用意しておくことをお勧めします。
・各サーバーの管理者アカウントが異なるユーザー名とメールアドレスを持っていることを確認してから、ユーザーデータでコースをバックアップして復元してみてください。
・・新しいバックアップを作成できず、既存の「競合する」バックアップファイルを使用しなければならない場合は、新しいサイトのメイン管理者アカウントを変更して、新しいメイン管理者のパスワードとメールアドレスを覚えておくように細心の注意を払う必要があります。
・インポートされたファイルの管理者アカウントはパスワードを失い、使用できなくなる可能性があることに注意してください。
・ログアウトする前に'インポートされた'メインの'admin'アカウントのパスワードを更新/リセットすることをお勧めします。
・何かがひどく間違った状態になった場合は、2番目の管理者アカウントを使ってメインの管理者アカウントを修正することができます。

11 関連項目

コースリストア
ユーザーデータのバックアップ
アクティビティのバックアップ

管理者はMOOSHを使用して、CLIからコースの一括バックアップとリストアを行うことができます。

カテゴリ バックアップ コース

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

Moodle 3.9 マニュアル - アクティビティ選択ツール

原文

アクティビティ選択ツールとは何ですか?

コースの編集がオンになっていて、「アクティビティまたはリソースの追加」リンクをクリックすると、アクティビティの選択画面が表示されます。

video
アクティビティ・チューザー

各項目には、お気に入りに登録するためのスターアイコンと、より詳細な情報やドキュメントを表示するための情報アイコンがあります。

StarInfo.png

新機能
Moodle 3.9で!

Moodle 3.9以降のMoodle 3.9では、アクティビティセレクタには異なるビューのためのタブがあります。どのタブが表示されるかは管理者の設定 (下記の管理者設定を参照) に依存し、以下を含むことができます。

スター付き - あなた (教師) がお気に入りまたは頻繁に使用するアクティビティリソースをスター付きで表示します。
すべて - すべての活動とリソースを一緒に
アクティビティ - アクティビティのみ
リソース - リソースのみ
推奨 - サイト管理 > コース > アクティビティセレクタ > 推奨アクティビティで管理者が選択した項目

管理者がMoodleNetとの統合を有効にしている場合、MoodleNetからコンテンツを閲覧するオプションがアクティビティセレクタの下部に表示されます。
管理者設定

サイト管理 > コース > アクティビティセレクタ > アクティビティセレクタの設定から、管理者はコース内のアクティビティセレクタのデフォルトのタブを定義することができます。
サイト管理 > コース > アクティビティセレクタ > アクティビティセレクタの推奨タブで、管理者はアクティビティセレクタの推奨タブに表示される項目を選択することができます。

カテゴリ コース 新機能

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

PHPの関数が使用前に定義しなくても呼び出せるのはなぜか

PHPの関数は使用前に定義しなくても呼び出せるという記事を書いてる途中にふとなぜそのような仕様になるのか疑問に思い,調べてみました.

注意:この記事は筆者が途中で力尽きたため,しっかりした根拠のある結論が出ていません.ご了承の上お読みください

調べた過程やリンク先について共有します,こちらについては役に立てるかと思います.

疑問

PHPはインタプリタ言語のはずなのに,定義前の関数を呼び出しても正常に呼び出せるのはなぜ?

調べてわかったこと

Zend OpCodesっていうのに一回コンパイルされるらしい

「how it works」をつけて調べてみました.以下の説明が非常にわかりやすかったです.

https://www.quora.com/How-does-the-PHP-interpreter-work/answer/Gaurav-Kumar-956?ch=2&srid=uBQqa0

あくまで推測ですが,この「Zend OpCodes」という中間バイナリコードの生成時に,関数は事前に読み込まれ定義されているように見えます.
もしかしたら,定義行のアドレスはここですよって参照が貼られているだけかもしれませんが.

関数は中間コード前処理の際になんかされるらしい

Q&Aサイトの記述ですが,それっぽい記載はありました.

The PHP compiler's job is to parse your PHP code and convert it into a form suitable for the runtime engine. Here are some of its functions:
  • Removes comments
  • Resolves variables, functions/methods and inserts relevant data into a symbol table
  • Constructs an abstract syntax tree of your program
  • Writes out the bytecode
...(中略)...
The symbol table is used to store the values of variables and provide the bytecode addresses for functions and methods. Otherwise, functions would have to be defined before use, which is clearly not the case.

https://www.quora.com/How-is-PHP-interpreted/answer/Ian-Atkin?ch=2&srid=uBQqa0

この説明によると,

  • シンボルテーブルに関数のバイトコードのアドレスが格納される
  • そのため,定義前に関数を呼び出そうとしても問題はない

と理解できました.

まだこの情報が間違っている可能性がアリアリ1なのですが,ちょっとこの辺りで終わろうと思います.
以下の情報が更に詳しそうですが,もはや理解できませんでしたw
https://blog.krakjoe.ninja/2016/03/hacking-php-7.html

参考資料他

Zend Engineについての説明:https://phpbuilder.com/php-and-zend-engine-internals/
ZendAPIについてのマニュアル説明(古い) - https://www.php.net/manual/en/internals2.ze1.zendapi.php
PHP組み込み関数の登録方法 - http://www.phpinternalsbook.com/php7/extensions_design/php_functions.html
OPCODES「DECLARE_FUNCTION」:https://www.php.net/manual/en/internals2.opcodes.declare-function.php#internals2.opcodes.declare-function
Sebastian Bergmann 氏の資料:https://www.scribd.com/document/18171982/PHP-Compiler-Internals


  1. 古い資料とかも参照したので,5系と7系で挙動が違ったりもしそうです 

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

PHPの関数は使用前に定義しなくても呼び出せる件について

有名な話だと思いますが,自分用まとめです.途中で気になって内部仕様について深堀りもしましたが途中で力尽きています.ご了承ください.

関数の定義より先に,その関数を呼び出すコードを記述することができる

以下のコードはエラーなく動作します.

<?php

 func();

 function func() {
     echo 'OK';
 }

https://3v4l.org/XWgHF

関数1の内部で定義した関数2は,関数1を呼び出した後でないと実行できない

以下コードはエラーなく動作します.

<?php

 func1();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/kiG23

しかし,以下は動作しません.

<?php

 func2();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/66faT

以下のように,func1() のあとにfunc2() を呼び出すようにするとエラーなく動作しますが,

<?php

 func1();
 func2();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/vPKBS

この順番を逆にすると動作しません.

<?php


https://3v4l.org/bpXPp

余談ですが,関数の内部だけでなく,if 文の内部で宣言された関数も同様の挙動になるみたいです.
定義前に呼び出そうとするとエラーが出ます.

<?php

 func1();

 if (true) {
    function func1() {
        echo 'func1';
    }
 }

定義後であれば大丈夫です.

<?php

if (true) {
   function func1() {
       echo 'func1';
   }
}

func1();

https://3v4l.org/c1KN9

定義後であっても,if 式の評価の結果関数定義部分が実行されないと同様に呼び出すことはできません.
以下のコードはエラーが発生します.

<?php

if (false) {
   function func1() {
       echo 'func1';
   }
}

func1();

https://3v4l.org/5MmRM

マニュアルでは以下の部分で記載されています.

PHP では、関数は参照される前に定義されている必要はありません。 ただし以下の二つの例のように、条件付きで関数が 定義されるような場合を除きます。
https://www.php.net/manual/ja/functions.user-defined.php

PHPはインタプリタ言語

注意:この先,筆者が力尽きていますのでしっかりとした結論が出ていません

ん?

ここでちょっと思いました.どうも,PHPインタプリタくんはファイルを実行した際,functionから始まる行について先に読み込んで,なにか処理をしているようです.

インタプリタ言語って上から一行ずつ読み込んでコンパイルして逐次実行していくイメージです.どういう順序で処理してるんでしょうか.

Zend OpCodesっていうのに一回コンパイルされるらしい

こういうときは「how it works」をつけて調べてみます.以下の説明が非常にわかりやすかったです.

https://www.quora.com/How-does-the-PHP-interpreter-work

あくまで推測ですが,この「Zend OpCode」という中間バイナリコードの生成時に,関数は事前に読み込まれ定義されているように見えます.
もしかしたら,定義行のアドレスはここですよって参照が貼られているだけかもしれませんが.

関数は中間コード前処理の際になんかされるらしい

Q&Aサイトの記述ですが,それっぽい記載はありました.

The PHP compiler's job is to parse your PHP code and convert it into a form suitable for the runtime engine. Here are some of its functions:
  • Removes comments
  • Resolves variables, functions/methods and inserts relevant data into a symbol table
  • Constructs an abstract syntax tree of your program
  • Writes out the bytecode
...(中略)...
The symbol table is used to store the values of variables and provide the bytecode addresses for functions and methods. Otherwise, functions would have to be defined before use, which is clearly not the case.

https://www.quora.com/How-is-PHP-interpreted

この説明によると,

  • シンボルテーブルに関数のバイトコードのアドレスが格納される
  • そのため,定義前に関数を呼び出そうとしても問題はない

と理解できました.

まだこの情報が間違っている可能性がアリアリ1なのですが,ちょっとこの辺りで終わろうと思います.
以下の情報が更に詳しそうですが,もはや理解できませんでしたw
https://blog.krakjoe.ninja/2016/03/hacking-php-7.html

参考資料他

Zend Engineについての説明:https://phpbuilder.com/php-and-zend-engine-internals/
ZendAPIについてのマニュアル説明(古い) - https://www.php.net/manual/en/internals2.ze1.zendapi.php
PHP組み込み関数の登録方法 - http://www.phpinternalsbook.com/php7/extensions_design/php_functions.html
OPCODES「DECLARE_FUNCTION」:https://www.php.net/manual/en/internals2.opcodes.declare-function.php#internals2.opcodes.declare-function
Sebastian Bergmann 氏の資料:https://www.scribd.com/document/18171982/PHP-Compiler-Internals


  1. 古い資料とかも参照したので,5系と7系で挙動が違ったりもしそうです 

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

PHPの関数は使用前に定義しなくても呼び出せる

有名な話だと思いますが,自分用まとめです.途中で気になって内部仕様について深堀りもしましたが途中で力尽きています.ご了承ください.

関数の定義より先に,その関数を呼び出すコードを記述することができる

以下のコードはエラーなく動作します.

<?php

 func();

 function func() {
     echo 'OK';
 }

https://3v4l.org/XWgHF

関数1の内部で定義した関数2は,関数1を呼び出した後でないと実行できない

以下コードはエラーなく動作します.

<?php

 func1();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/kiG23

しかし,以下は動作しません.

<?php

 func2();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/66faT

以下のように,func1() のあとにfunc2() を呼び出すようにするとエラーなく動作しますが,

<?php

 func1();
 func2();

 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }

https://3v4l.org/vPKBS

この順番を逆にすると動作しません.

<?php


https://3v4l.org/bpXPp

余談ですが,関数の内部だけでなく,if 文の内部で宣言された関数も同様の挙動になるみたいです.
定義前に呼び出そうとするとエラーが出ます.

<?php

 func1();

 if (true) {
    function func1() {
        echo 'func1';
    }
 }

定義後であれば大丈夫です.

<?php

if (true) {
   function func1() {
       echo 'func1';
   }
}

func1();

https://3v4l.org/c1KN9

定義後であっても,if 式の評価の結果関数定義部分が実行されないと同様に呼び出すことはできません.
以下のコードはエラーが発生します.

<?php

if (false) {
   function func1() {
       echo 'func1';
   }
}

func1();

https://3v4l.org/5MmRM

マニュアルでは以下の部分で記載されています.

PHP では、関数は参照される前に定義されている必要はありません。 ただし以下の二つの例のように、条件付きで関数が 定義されるような場合を除きます。
https://www.php.net/manual/ja/functions.user-defined.php

PHPはインタプリタ言語

注意:この先,筆者が力尽きていますのでしっかりとした結論が出ていません

ん?

ここでちょっと思いました.どうも,PHPインタプリタくんはファイルを実行した際,functionから始まる行について先に読み込んで,なにか処理をしているようです.

インタプリタ言語って上から一行ずつ読み込んでコンパイルして逐次実行していくイメージです.どういう順序で処理してるんでしょうか.

この疑問については別記事に分割しました.ただ,根拠のある結論は出ていませんので,ご了承ください.

PHPの関数が定義前に呼び出せるのはなぜか

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

Moodle 3.9 マニュアル - 最近の活動のブロック

原文

最近の活動のブロック

内容

1 ユーザーが最後にコースにアクセスしてからのアクティビティの表示
2 最近の活動の完全なレポート
3 サイト管理の設定
4 ケイパビリティ
5 関連項目

1 ユーザーが最後にコースにアクセスしてからのアクティビティの表示

一人を除いた全員が部屋を出て、出て行った人が一つだけ変更して、戻ってきた全員が変更したものを見つけなければならないゲームを知っていますか?

最近のアクティビティブロックを有効にすると、参加者が最後にコースにアクセスしてからの更新情報が表示されます。

これがないと (あなたがわざわざ参加者に通知しない限り)、学生や同僚は修正や追加などの変更を見逃してしまいます。

最近の活動ブロックは重要なことを見落としているのではないかと心配している学生の多くの不安を和らげることができます。

最近の活動ブロックはユーザーが最後にコースにアクセスしてからの更新されたリソースや活動、フォーラムへの投稿や課題提出などのコース活動を一覧表示します。

Folderrecentactivity.png

最近の活動ブロック

300px-recentactivityfullreport.png
最近の活動の全容報告

2 最近の活動の完全なレポート

最近の活動の完全なレポートは、最近の活動ブロックのリンクからアクセスすることができます。これにより、時間フィルターとコースセクション別の活動を整理した画面につながります。

高度な検索ボタンまたはリンクには、より多くのフィルターオプションがあります。これらには、すべてまたは特定の項目(参加者、アクティビティ、日付以降)の選択が含まれています。また、コース順、古い順、最近の順、最近の順に並べ替えることもできます。通常の検索画面に戻るリンクがあります。

3 サイト管理の設定

サイト管理 > プラグイン > アクティビティモジュール > 課題の設定assignment_showrecentsubmissionsは学生が他の学生の最近の課題提出を見ることができるかどうかを決定します。教師は常にすべての最近の提出課題を見ることができ、学生は常に自分の最近の提出課題を見ることができます。

4 ケイパビリティ

最近の活動ブロックで追加された更新されたモジュールを表示
最近の活動ブロックで削除されたモジュールを表示

5 関連項目

リポート

カテゴリー ブロック サイト管理 コース

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

PHP Version 5.4.31 から PHP Version 7.4.10 への移行でつまずいた事まとめ

PHP Version 5.4.31 から PHP Version 7.4.10 への移行にあたって、つまずいた事をまとめてみました。

この記事では Windows 10 Pro にインストールした、pleiades-2020-09-ultimate-win-64bit-jre_20200920.zip を使っています。

PEAR::Auth

PEAR::Auth のインストール

pear install -a Auth MDB2 MDB2#MysqliAuth

でつまずきました。

xamppのPHP、pearのupgradeをしてみる、DBを入れてみる件
を参照して、解決しました。

.htaccess の修正

 .htaccess(修正前)
<IfModule mod_php5.c>
  php_value auto_prepend_file "include/MyAuth.php"
</IfModule>
・・・後略・・・

と書いているのに MyAuth.php の処理を通りませんでした。

http://localhost/dashboard/phpinfo.php
の「Loaded Modules 」で確認してみたら、
mod_php5 でなく mod_php7 にバージョンアップしていました。
なので、<IfModule mod_php7.c> を追記しました。

 .htaccess(修正後)
<IfModule mod_php5.c>
  php_value auto_prepend_file "include/MyAuth.php"
</IfModule>

<IfModule mod_php7.c>
  php_value auto_prepend_file "include/MyAuth.php"
</IfModule>
・・・後略・・・

pear/Auth.php のソースを修正

new の前の & を削除

XX\xampp\apache\logs\error.log
・・・前略・・・
[Tue Oct 13 20:47:32.722548 2020] [php7:notice] [pid 36512:tid 1916] [client ::1:56879] PHP Parse error:  syntax error, unexpected 'new' (T_NEW) in XX\\xampp\\php\\pear\\Auth.php on line 469
・・・後略・・・

new の前の & を削りました。

XX\xampp\php\pear\Auth.php(修正前)
    function &_factory($driver, $options = '')
    {
        $storage_class = 'Auth_Container_' . $driver;
        include_once 'Auth/Container/' . $driver . '.php';
        $obj =& new $storage_class($options);
・・・後略・・・
XX\xampp\php\pear\Auth.php(修正後)
    function &_factory($driver, $options = '')
    {
        $storage_class = 'Auth_Container_' . $driver;
        include_once 'Auth/Container/' . $driver . '.php';
//        $obj =& new $storage_class($options);
        $obj = new $storage_class($options);
・・・後略・・・

pear/MDB2.php のソースを修正 ※結局 MDB2 を使うのを断念

new の前の & を削除

PHPの実行結果のエラー表示.
Parse error: syntax error, unexpected 'new' (T_NEW) in XX\xampp\php\pear\MDB2.php on line 390

new の前の & を削りました。

XX\xampp\php\pear\MDB2.php(修正前)
・・・前略・・・
        $db =& new $class_name();
        $db->setDSN($dsninfo);
        $err = MDB2::setOptions($db, $options);
        if (PEAR::isError($err)) {
            return $err;
        }
・・・他にも& new多数あり・・・
XX\xampp\php\pear\MDB2.php(修正前)
・・・前略・・・
//        $db =& new $class_name();
        $db = new $class_name();
        $db->setDSN($dsninfo);
        $err = MDB2::setOptions($db, $options);
        if (PEAR::isError($err)) {
            return $err;
        }
・・・他にも& new多数あり・・・

count の仕様変更に対応

PHP7.3バージョンアップでcount関数エラー
を参照して、
旧countと同じ動作をする、get_countを追加して、
countをget_countに置換しました。

PHPの実行結果のエラー表示.その2
Parse error: syntax error, unexpected 'new' (T_NEW) in XX\xampp\php\pear\MDB2.php on line 1889
XX\xampp\php\pear\MDB2.php(修正前)
・・・前略・・・
    function parseDSN($dsn)
    {
・・・中略・・・
        if (!count($dsn)) {
            return $parsed;
        }
・・・他多数・・・
XX\xampp\php\pear\MDB2.php(修正後)
・・・前略・・・
// 旧countと同じ動作をする、get_countを追加
if (!function_exists('get_count')) {
    function get_count($var) {
        return ((is_array($var) || $var instanceof Countable)?count($var):0);
    }
}
・・・中略・・・
    function parseDSN($dsn)
    {
・・・中略・・・
//        if (!count($dsn)) {
        if (!get_count($dsn)) {
            return $parsed;
        }
・・・他多数・・・

\xampp\php\pear\MDB2\Driver\mysqli.php

new の前の & を削除

Parse error: syntax error, unexpected 'new' (T_NEW) in xx\xampp\php\pear\MDB2\Driver\mysqli.php on line 940
xx\xampp\php\pear\MDB2\Driver\mysqli.php(修正前)
・・・前略・・・
        $obj =& new $class_name($this, $statement, $positions, $query, $types, $result_types, $is_manip, $limit, $offset);
・・・中略・・・
                $row = &new $object_class($row);
・・・後略・・・
xx\xampp\php\pear\MDB2\Driver\mysqli.php(修正後)
//        $obj =& new $class_name($this, $statement, $positions, $query, $types, $result_types, $is_manip, $limit, $offset);
        $obj = new $class_name($this, $statement, $positions, $query, $types, $result_types, 
・・・中略・・・
//                $row = &new $object_class($row);
                $row = new $object_class($row);
・・・後略・・・

pear/MDB2.php を使うのを断念

ここまで修正してきても、下記のエラーが出るので、pear/MDB2.php を使うのを断念

Fatal error: Call to undefined function: MDB2_Driver_mysqli::raiseError(). in C:\pleiades-2020-09\xampp\php\pear\MDB2.php on line 1960

Call Stack
#   Time    Memory  Function    Location
1   0.0175  419536  {main}( )   ...\MyAuth.php:0
2   25.7579 542648  Auth->start( )  ...\MyAuth.php:70
3   25.7581 542648  Auth->login( )  ...\Auth.php:535
4   25.7641 1215208 Auth_Container_MDB2->fetchData( ???, ???, ??? ) ...\Auth.php:563
5   25.7641 1215208 Auth_Container_MDB2->_prepare( )    ...\MDB2.php:298
6   25.7641 1215208 Auth_Container_MDB2->_connect( ??? )    ...\MDB2.php:170
7   25.7641 1215208 MDB2::connect( ???, ??? )   ...\MDB2.php:114
8   25.7657 1441576 MDB2_Driver_mysqli->connect( )  ...\MDB2.php:458
9   25.7771 1441736 MDB2_Driver_mysqli->raiseError( ???, ???, ???, ???, ??? )   ...\mysqli.php:437
10  25.7772 1443424 MDB2_Driver_mysqli->raiseError( ???, ???, ???, ???, ???, ???, ??? ) ...\MDB2.php:1462
11  25.7772 1443800 MDB2_Driver_mysqli->__call( ???, ??? )  ...\MDB2.php:1462
12  25.7772 1444632 trigger_error ( ???, ??? )  ...\MDB2.php:1960

PEAR::Auth で PDO を使う

PEAR::AuthにPDOのContainerを追加してみる(検証中)
と、
php7・PDOでも認証ライブラリでSentinelではなくPEAR::Authを使った
を参照し、
xx\xampp\php\pear\Auth\Container
に、PDO.php を追加

PDO を使うために、認証処理用の自前プログラム MyAuth.php を下記の通り修正しました。

MyAuth.php(修正前)
<?php
require_once 'Auth/Auth.php';
・・・中略・・・
$params = array (
        'dsn' => 'mysqli://' . DB_USERNAME . ':' . DB_PASSWD . '@' . DB_HOST . '/' . DB_DBNAME,
        'table' => AUTH_TABLE,
        'usernamecol' => AUTH_USERNAME_COL,
        'passwordcol' => AUTH_PASSWORD_COL
);
$auth = new Auth ( 'MDB2', $params, 'myLogin' );
・・・後略・・・
MyAuth.php(修正後)
<?php
require_once 'Auth/Auth.php';
・・・中略・・・
$options = array (
    // コネクションプーリング
    // 1つのコネクションを使いまわすのがボトルネックとなりスケールしないため、
    // スレッドキャッシュ(max_connections、thread_cache_size指定)との合わせ技で、
    // コネクションプーリングの設定を、コメントアウトする。
    // PDO::ATTR_PERSISTENT => true,
    // エラー時に例外を投げる
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
$params = array (
    'table' => AUTH_TABLE,
    'usernamecol' => AUTH_USERNAME_COL,
    'passwordcol' => AUTH_PASSWORD_COL,
    'dsn' => 'mysql:dbname=' . DB_DBNAME . '; host=' . DB_HOST . '; charset=utf8',
    'db_fields' => '',
    'cryptType'=> 'md5',
    'db_options'  => $options,
    'db_where' => '',
    'auto_quote' => false,
    'db_user' => DB_USERNAME,
    'db_password' => DB_PASSWD
);
$auth = new Auth ( 'PDO', $params, 'myLogin' );

count の仕様変更

PHP7.2のcountにハマった話

        // count の仕様変更に対応
        //if (0 < count ( $map )) {
    // NULLチェックに使えなくなった。
        if (0 < isset ( $map )) {
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Moodle 3.9 - コースFAQ

原文

コースFAQ

内容
1 コースの説明にある教師の名前を削除するにはどうすればよいですか?
2 編集していない教師の名前をコースの説明に追加するにはどうすればよいですか?
3 私のコースの中には、コースの概要が表示されているものもありますが、情報アイコンしかないものもあります。どうして?
4 コースにファイルをアップロードできません。 「ファイルタイプを受け入れることができません」というメッセージが表示されます
5 教師が特定のリソースやアクティビティを追加できないようにするにはどうすればよいですか?
6 [アクティビティまたはリソースの追加]リンクの代わりに2つのドロップダウンボックスが表示されます
7 復元したコースで将来の日付を取得するのはなぜですか?
8 コースのホームページをWebページのように見せるためにどうすればよいですか?
9 すべてのコースリソースとアクティビティのリストはどこにありますか?
10 コースへのショートカットURLはありますか?
11 形式をある形式から別の形式に変更すると、コースの内容はどうなりますか?
12 アクティビティの多いコースでアイテムを簡単に移動するにはどうすればよいですか?
13 コースを複数のカテゴリに分類できますか?

1 コースの説明にある教師の名前を削除するにはどうすればよいですか?

デフォルトでは、Moodleはコースの説明に教師の名前を表示します。これが不要な場合は、[管理]> [サイト管理]> [外観]> [コースの連絡先]で役割のチェックを外してください。

2 編集していない教師の名前をコースの説明に追加するにはどうすればよいですか?

デフォルトでは、Moodleはコースの説明に教師の名前のみを表示します。他の役割を追加する場合は、[管理]> [サイト管理]> [外観]> [コースの連絡先]で役割を確認してください。

3 私のコースの中には、コースの概要が表示されているものもありますが、情報アイコンしかないものもあります。どうして?

コースが10未満のカテゴリには完全な要約が表示されますが、コースが多いカテゴリには情報アイコンのみが表示されます。それらすべてに完全な要約を表示する場合は、[サイト管理]> [外観]> [コース]で[要約付きコースの制限(courseswithsummarieslimit)]設定の値を変更します。

4 コースにファイルをアップロードできません。「ファイルタイプを受け入れることができません」というメッセージが表示されます

コース管理の[設定の編集]領域にあるコース概要ファイル領域にアップロードしようとしていないことを確認してください。
このアップロード領域は、コースを説明するファイル専用であり、デフォルトでは画像ファイルのみが許可されます(要約の横にスクリーンショットが表示されるようにするため)。
コースにファイルをアップロードする場合は、コースの設定ではなく、メインコースページ自体を最初に表示するようにしてください。

5 教師が特定のリソースやアクティビティを追加できないようにするにはどうすればよいですか?

[サイト管理]> [ユーザー]> [権限]> [役割の定義]から、教師の役割を編集し、追加しないモジュールの機能で[許可]のチェックを外します(例:mod /ワークショップ:追加)

6 [アクティビティまたはリソースの追加]リンクの代わりに2つのドロップダウンボックスが表示されます

ユーザー設定をチェックイン> [アクティビティチューザーを有効にする]がオンになっているコース設定
Ajaxが有効になっていることを確認してください。Ajaxが有効になっていないとリンクは表示されません。

7 復元したコースで将来の日付を取得するのはなぜですか?

ユーザーデータを使用してコースを復元したが、現在の登録日を設定した場合、ログ、フォーラムの投稿などは、コースの開始から同じ時間距離に設定されます。したがって、元のコースが2010年に始まり、参加者が2012年にフォーラムに投稿した場合、コースを復元して2014年に開始すると、それらの投稿にはすべて2016年の日付が付けられます。 MDL-44961を参照

8 コースのホームページをWebページのように見せるためにどうすればよいですか?

多くの場合、コースに多くのコンテンツがある場合、学生と教師は長いスクロールが面倒であり、Webサイトのページが機能するのと同じようにセクションへのハイパーリンクを備えた「すっきりとした」外観を好むでしょう。

Moodleコースでこれを行う方法については、ステルスアクティビティを参照してください。

9 すべてのコースリソースとアクティビティのリストはどこにありますか?

リソース(静的ページやフォルダーなど)のリストは、次の場所にあります。

http://yourmoodlesite.net/course/resources.php?id=x

ここで、xはコースID番号です。クイズなどのアクティビティのリストを表示したい場合は、次のようなURLを使用してください

http://yourmoodlesite.net/mod/quiz/index.php?id=x

ここで、xはコースID番号です。

リストに表示する必要のあるアクティビティに応じて、アクティビティ名を変更します。

10 コースへのショートカットURLはありますか?

コースの短縮名を使用してこれを試してください:URL(Moodlesite)/course/view.php?name=shortnameコースに直接移動します。

クリーンURLのトラッカーアイテムを確認してください:MDL-28030

11 形式をある形式から別の形式に変更すると、コースの内容はどうなりますか?

標準コース形式の場合のみ:トピックからウィークリーまたはウィークリーからトピックに変更した場合、実際の違いはセクションのタイトルだけになります。ソーシャル形式に変更すると、フォーラムができます。それでも他のアクティビティにアクセスしたい場合は、「ソーシャルアクティビティブロック」を追加する必要があります。シングルアクティビティ形式に変更すると、表示するように選択したアクティビティのみが表示され、他のアクティビティは生徒には表示されませんが、灰色のセクションで利用できます。その後、シングルアクティビティからトピックまたはウィークリー形式に戻す場合は、それらのセクションを再表示する必要があります。

12 アクティビティの多いコースでアイテムを簡単に移動するにはどうすればよいですか?

忙しいコースでアクティビティやリソースを移動するときにスクロールの問題を回避できる方法については、コースホームページのヒントとコツのセクションを参照してください。

13 コースを複数のカテゴリに分類できますか

いいえ。ただし、回避策があります。シングルアクティビティコース形式では、シングルアクティビティとしてURLを追加することができます。 URLは、別のカテゴリのコースへのリダイレクトにすることができるため、複数のカテゴリのコースのように見えます。
カテゴリコースFAQ

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

【Laravel】get〜Attributeメソッド

はじめに

今回はLaravelのget〜Attributeメソッドを利用して、欲しい値を加工する方法をまとめたいと思います。

アクセサについて

アクセサを定義するには、アクセスしたいカラム名が「studlyケース(Upper Camel Case)」でFooの場合、getFooAttributeメソッドをモデルに作成します。以下の例では、first_name属性のアクセサを定義しています。first_name属性の値にアクセスが起きると、Eloquentは自動的にこのアクセサを呼び出します。

参考:Eloquent:ミューテタ 8.x Laravel

get〜Attributeメソッドの実装例

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーの氏名を取得
     *
     * @param  string  $value
     * @return string
     */
    public function getFullNameAttribute($value)
    {
        return "{$this->first_name} {$this->last_name}";
    }
}

モデルにこのように定義するとこの値を使用したいコントローラー層やサービス層などで、例えば$this->full_nameのように実装すると値を取得することができます。

おわりに

いかがでしたでしょうか。
get〜Attributeメソッドはとても便利なので是非活用してみてください。

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

マトリクスのパターンを網羅するロジックの書き方

この記事を書いた理由

よくテスト実施の際に以下のようなパターンを網羅するための表を書くことがあると思う。

Aデータ Bデータ
×
×
× ×

このパターン網羅をコーディングテストをする際に必要になることがある。
これをプログラミングで書くまでが結構大変だったのでメモしておく。

プログラム

以下のように書くとパターン表がざっくり取得できる。

<?php
$num = 4; // true/falseの4つのデータがある時
for ($i = 0; $i < (1 << $num); $i++) {
  for ($j = $num - 1; $j >= 0; $j--) {
    if ($i & (1 << $j)) {
      echo '×';
    } else {
      echo '○';
    }
  }
  echo PHP_EOL;
}

「<<」や「&」はシフト演算子である。
2進数で値をシフトすることによりパターン網羅の処理が格段に簡単になる。

上記の出力内容は以下のようになる。

○○○○
○○○×
○○×○
○○××
○×○○
○×○×
○××○
○×××
×○○○
×○○×
×○×○
×○××
××○○
××○×
×××○
××××

テーブルっぽく書きたいなら多重配列に入れて、テーブルに起こしてあげるといい

<?php
echo array2table(create_pattern(4)); // true/falseの4つのデータがある時

function create_pattern($num){
  $board = [];
  for ($i = 0; $i < (1 << $num); $i++) {
    for ($j = $num - 1; $j >= 0; $j--) {
      if ($i & (1 << $j)) {
        $board[$i][] = '×';
      } else {
        $board[$i][] = '○';
      }
    }
  }
  return $board;
}

// 参考:https://www.pahoo.org/e-soul/webtech/php02/php02-46-01.shtm#array2table
function array2table($arr) {
  if (!is_array($arr)) return false;
  $keys1 = array_keys($arr); //1次元目のキー取得
  $keys2 = array_keys($arr[$keys1[0]]); //2時限目のキー取得
  if (is_array($arr[$keys1[0]][$keys2[0]])) return false; //3次元以上

  $n = count($arr[$keys1[0]]); //要素の数
  $html = "<table class=\"array\">\n";

  //要素名
  $html .= "<tr><th>Key</th>";
  for ($i = 0; $i < $n; $i++) {
    $html .= "<th>{$keys2[$i]}</th>";
  }
  $html .= "</tr>\n";

  //配列本体
  foreach ($arr as $key=>$arr1) {
    $html .= "<tr><th>{$key}</th>";
    for ($i = 0; $i < $n; $i++) {
      $html .= "<td>{$arr1[$keys2[$i]]}</td>";
    }
  }
  $html .= "</tr>\n</table>\n";

  return $html;
}

htmlで出力すると以下のような感じで表示される。

aaa_html.png

上記のパターン網羅プログラム、コーディングテスト等で必要になる機会が多い印象がある。
便利なのでぜひ活用してみてほしいです。

参考

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

[PHP]UTF-8で多言語をファイル出力する際に文字化けする

PHPでUTF-8で中国語をテキストファイルに出力すると、開くアプリケーションによって文字化けが起こる事象に遭遇した。

元のプログラム

<?php

$filePath = 'mojibake.txt';
$value = '你好';

$fh = fopen($filePath, 'w');
fwrite($fh, mb_convert_encoding($value, 'UTF-8'));
fclose($fh);

途中の処理は省略している。

$ cat mojibake.txt
你好%

ちゃんと出力されているし、Macのテキストエディタで開いても正しく表示される。しかしこれをExcelで開くと...
スクリーンショット 2020-10-17 5.08.55.png
こんな感じで文字化けしてしまう。

原因

アプリケーションによって、Unicodeの符号化方式が判別できず、UTF-8・UTF-16・UTF-32を判別できないため、文字化けが起きてしまう。

解決策

上を判別させるために、ファイル出力時の先頭にBOMをつける。

BOMとは

BOMとは、Byte Order Markの略称で、Unicodeの符号化方式を判別するために、ファイルの先頭につける数バイトのマーク。

プログラムがテキストデータを読み込む時、その先頭の数バイトからそのデータがUnicodeで表現されていること、また符号化形式(エンコーディング)としてどれを使用しているかを判別できるようにしたものである。
バイトオーダーマーク - Wikipedia

BOMは以下の通り。

符号化形式 エンディアンの区別 BOM
UTF-8 0xEF 0xBB 0xBF
UTF-16 BE 0xFE 0xFF
UTF-16 LE 0xFF 0xFE
UTF-32 BE 0x00 0x00 0xFE 0xFF
UTF-32 LE 0xFF 0xFE 0x00 0x00

今回はUTF-8なので、0xEF 0xBB 0xBFを先ほどのファイルの先頭につけるようにする。

修正したプログラム

<?php

$filePath = 'mojibake.txt';
$value = '你好';

$fh = fopen($filePath, 'w');

// add BOM
fwrite($fh, "\xEF\xBB\xBF");

fwrite($fh, mb_convert_encoding($value, 'UTF-8'));
fclose($fh);

Excelで開いても、正しく表示されるようになった。
スクリーンショット 2020-10-17 5.35.40.png

BOM付かどうかファイル情報を調べる

ファイルにBOMが付いているかはコマンドで調べることができる。

$ file mojibake.txt
mojibake.txt: UTF-8 Unicode (with BOM) text, with no line terminators

BOMが付いているとwith BOMと表示される。

$ file mojibake2.txt
mojibake2.txt: UTF-8 Unicode text, with no line terminators

BOMがない場合は表示されない。

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