- 投稿日:2020-09-13T22:05:01+09:00
VSCodeでphpをデバッグする
環境
初書:2020/09/13
PC:macOS 10.15.6
php 7.4.9
xdebug 2.9.6前置き
PHPでもデバッグしたい!という事で、デバッグする方法を探してみた。
前提
peclが利用可能な環境・vscodeがインストール済み
debugをインストールする
PHP debug
vscodeの拡張機能から、PHP Debugをインストールする
(publisher:Felix Becker。他の人のでも動くかは未検証)xdebug
ターミナルから、
% pecl install xdebug
を実行し、xdebugをインストール
% pecl list
を実行し、xdebugが表示されればインストールは完了php.iniを設定する
% vim /usr/local/etc/php/7.4/php.ini(※phpのバージョン及びphp.iniの場所によって座標は変更する。)
を実行し、以下のコードを追加する(一番上に書き足しても動く)zend_extension="/usr/local/Cellar/php/7.4.9/pecl/20190902/xdebug.so" xdebug.remote_enable=1 xdebug.remote_autostart=1 xdebug.remote_port = 8080(zend_extensionには、xdebugをインストールした際に
Installing '(略)'
と記載されているので、その値。
xdebug.remote_portには、普段phpを立てる際のポート番号を設定する)2020/09/15 追記
各項目の説明をしてくれているサイトをがあったので:[PHP] Xdebug のリモートデバッグ、理解していますか?vimの操作覚えてないのでメモ:Vim初心者のための基本的な操作方法のまとめ
vscodeを設定する
vscodeのデバッグ画面(command + shift + D)を開き、上部にある歯車のマークをおし、launch.jsonを開く
"port"欄を、xdebug.remote_portと同じ値にするphpを実行する
設定は終わったので、動作するか確認する
vscodeのphpファイルで適当にブレークポイントを入れ、下記を実行する% php -S XXXX:8080
(XXXX及び8080は自身の環境に応じて変更する)
その後、該当ページにアクセスし、ブレークポイントで止まれば完了する。終わりに
こちらの環境では、ブレークポイントで止まるものの、何行目で止まっているのかの表示がされないのでもしかしたらどこかで設定ミスがあるかもしれない。
また、デバッグの設定は過去に一度断念しているらしく、一部設定がしてあったり、インストールされていたりしたので、もしかしたら上記設定以外にも必要かもしれないが、覚えていない。。2020/09/15 追記
xdebugは、var_dumpの表示方法を変えるシステムが存在しているらしく、出力が少し変わった。
もし気になる場合はautostartにしない方がいいかもしれない。参考サイト:
Visual Studio CodeとXdebugでPHPのデバッグ環境を構築する
[XAMPP Mac]VSCodeでPHPのXdebugを使いデバッグ!しかしブレークポイントが止まらない
- 投稿日:2020-09-13T21:54:40+09:00
【PHPメモ】in_arrayで重複をチェック
0.目的
自分用のメモ
1.重複文字問題
(1)112233が入力の時
⇒123
(2)233342213が入力の時
⇒2341
のように出力するプログラムを作る。2.メモ
in_array(検索対象文字列,配列):配列の中に検索対象文字列が存在するか確認する関数、存在する場合true,存在しない場合false
3.コード
※paiza.IOで動作確認
<?php $in1 = fgets(STDIN); $in1=trim($in1); $len1=strlen($in1); //重複を取り除いた文字配列 $arr_dict=[]; for($i=0;$i<$len1;$i++){ //$in1の1文字が$arr_dict配列に含まれない時 if(!in_array(substr($in1,$i,1),$arr_dict)){ $ans=substr($in1,$i,1); $arr_dict[]=$ans; echo $ans; } } ?>入力
1234904743521627489064953371426326487539813121258593765158596901918出力
1234907568
- 投稿日:2020-09-13T17:51:45+09:00
array_push の返り値
array_push の返り値は処理後の配列そのものではなく、配列の要素数なので、書き方には気を付けなければいけません。
example.php$ex_array = array(); array_push($ex_array, 'youso'); //$ex_array = array_push($ex_array, 'youso1'); ではエラーになる
- 投稿日:2020-09-13T17:31:00+09:00
Laravel 8 の新機能!マイグレーションスカッシングで肥大化したマイグレーションファイルを1つにまとめる
大規模または長期間運用されているアプリケーションでは、
数年以上前に作成されたマイグレーションファイルが膨大な数になってきます。データベーステストを行っているプロジェクトでは、マイグレーションを適用するのに時間がかかりテストの速度が低下する懸念があります。
これの解決策として、Laravel 8ではマイグレーションスカッシング(スキーマダンプ)と呼ばれる新機能が追加されました。
mysqldump
まはたpgdump
を使用して現在のスキーマの状態からダンプを作成します。
(MySQL、PostgreSQL、SQLiteデータベースのみサポート)公式ドキュメント・ソース
- https://readouble.com/laravel/8.x/ja/migrations#squashing-migrations
- https://laravel.com/api/8.x/Illuminate/Database/Console/DumpCommand.html
- https://github.com/laravel/framework/blob/8.x/src/Illuminate/Database/Console/DumpCommand.php
マイグレーションファイルを確認
初期状態のままですが...下記のマイグレーションファイルがあるとします。
$ ls -1 database/migrations 2014_10_12_000000_create_users_table.php 2014_10_12_100000_create_password_resets_table.php 2019_08_19_000000_create_failed_jobs_table.phpスキーマダンプ コマンド
$ php artisan schema:dump
--prune
オプションを付けると、既存のマイグレーションファイルの削除が行われます。$ php artisan schema:dump --prune
database/schema/mysql-schema.sql
が生成されます。
/database/schema/<DB_CONNECTION>-schema.mysql
database/schema/mysql-schema.sql/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `failed_jobs` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `uuid` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `connection` text COLLATE utf8mb4_unicode_ci NOT NULL, `queue` text COLLATE utf8mb4_unicode_ci NOT NULL, `payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL, `failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `migrations` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `migration` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `batch` int NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `password_resets` ( `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `token` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` timestamp NULL DEFAULT NULL, KEY `password_resets_email_index` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `users` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `email_verified_at` timestamp NULL DEFAULT NULL, `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `users_email_unique` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; INSERT INTO `migrations` VALUES (1,'2014_10_12_000000_create_users_table',1); INSERT INTO `migrations` VALUES (2,'2014_10_12_100000_create_password_resets_table',1); INSERT INTO `migrations` VALUES (3,'2019_08_19_000000_create_failed_jobs_table',1);
migrations
以外のテーブルのデータはダンプされず、テーブル構成のみダンプされるみたいです。(マイグレーションなのにデータまでダンプされたら困りますが...)マイグレーションを実行する
$ php artisan migrate:reset $ php artisan migrate Loading stored database schema: /Users/ucan-lab/laravel-love/backend/database/schema/mysql-schema.sql Loaded stored database schema. (128.57ms) Nothing to migrate.
mysql-schema.sql
が読み込まれて、既存のマイグレーションファイルは無視されてます。スキーマダンプのメリット
前述の通り、データベーステストが高速化されるメリットがあります。
また、スキーマダンプはマイグレーションファイルではなく
mysqldump
コマンドを使って現在のデータベースからダンプファイルを作成されています。
本来の用途とは違うかもしれませんが、マイグレーションファイルでデータベースが管理されていないプロジェクトからLaravelに移行する際はとても役に立つ機能ではないでしょうか。使ってみた感想
mysqldump
コマンドをLaravelで実行しているので、Dockerでやろうとするとmysqldump
コマンドをコンテナ内で使えるようにしてあげる必要があるし、debianのdefault-mysql-client
はMariaDBに統合されたようでLaravelで実行しているオプションが存在していなかったりとDockerで頑張ろうとすると手間かもしれません...今回はローカルで試してみました。参考
- 投稿日:2020-09-13T17:23:20+09:00
【PHP】デバッグ
PHPについて学習内容を備忘録としてまとめます。
デバッグについて
開発中にエラーが発生した際に、デバッグをすると思います。
その中でも私がデバッグ方法を記載します。var_dump
コードの中で値を確認する際に利用することができます。
例えば、下記のような従業員がログインするコードで見ていきます。#staff_login.php <form method="post"action="staff_login_cheak.php"> スタッフコード<br /> <input type="text" name="code"><br /> パスワード<br /> <input type="password" name="pass"><br /> #staff_mypage.php $staff_code=$_POST['code']; $staff_pass=$_POST['pass']; var_dump($staff_code);※本当は間にDBから該当のユーザーを取得する処理がありますが、省略しています。
このように記載すると、staff_login_cheak.php
にスタッフコードフォームで記入したコード番号が表示されます。↓ ログイン
デバッグを別ファイルで管理
ajaxなどでデバッグを実施する際に、上記のやり方だと表示されません。
バックエンドの処理なので一度デバッグ情報をファイルに出力する方法をとります。方法としては_debug()という関数を作成し、引数に確認したい値等を入れると表示される処理を行います。
#_debug()関数を作成 function _debug( $data, $clear_log = false ) { $uri_debug_file = $_SERVER['DOCUMENT_ROOT'] . '/debug.txt'; if( $clear_log ){ file_put_contents($uri_debug_file, print_r($data, true)); } file_put_contents($uri_debug_file, print_r($data,true), FILE_APPEND); }上記関数は自分がわかるところで作成してください。
それではいいね機能のajaxファイルにて、いいねした際のデバッグを見ていきます。if(isset($_POST)){ $current_user = get_user($_SESSION['staff_code']); $page_id = $_POST['page_id']; $post_id = $_POST['post_id']; $profile_user_id = $_POST['page_id'] ?: $current_user['id']; if(check_favolite_duplicate($current_user['code'],$post_id)){ $action = '解除'; $sql = "DELETE FROM favorite WHERE :user_id = user_id AND :post_id = post_id"; }else{ $action = '登録'; $sql = "INSERT INTO favorite(user_id,post_id) VALUES(:user_id,:post_id)"; } _debug($action); //ここを追加いいねボタンを押した結果、設定した
debug.txt
にて$action
の値が入っていればデバッグ成功です。解除が追記されている。
_debug()関数は_debug('',true)と定義するとdebug.txtが空になるように作成されています。参考URL
- 投稿日:2020-09-13T14:50:32+09:00
Laravelでサブドメイン対応(さくらレンタルサーバ)
やりたいこと
main.hoge.hoge → routes/main.phpでルーティング
api.hoge.hoge → routes/api.phpでルーティング
test.hoge.hoge → routes/test.phpでルーティング①テスト環境と本番環境でドメインを分けるためにconfig設定
configフォルダ内にmyapp.php作成
\Config::get('myapp.domain.main')でアクセスできるconfig/myapp.php<?php return [ 'domain' => [ 'main' => 'main.hoge.hoge', 'api' => 'api.hoge.hoge', 'test' => 'test.hoge.hoge', ] ];コンフィグファイルのキャッシュクリアをしないと反映されない。
$ php artisan config:cache②ルーティング設定
/app/Providers/RouteServiceProvider.phpclass RouteServiceProvider extends ServiceProvider { public function map() { $this->mapApiRoutes(); //$this->mapWebRoutes(); $this->mapMainRoutes(); $this->mapTestRoutes(); } protected function mapMainRoutes() { Route::domain(\Config::get('myapp.domain.main')) ->middleware('web') ->namespace($this->namespace) ->group(base_path('routes/main.php')); } protected function mapTestRoutes() { Route::domain(\Config::get('myapp.domain.test')) ->middleware('web') ->namespace($this->namespace) ->group(base_path('routes/test.php')); } protected function mapApiRoutes() { Route::domain(\Config::get('api.domain.test')) ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); }routes/main.php,routes/test.phpを作ってルーティングさせる。
おわり。
CROS対応
サブドメインで分けるとaxiosからの通信がクロスドメインで引っかかるので設定
※バージョン指定しないとエラーになります。$ composer require barryvdh/laravel-cors:^0.11続きは下記参照
Laravelでクロスオリジン(CORS)に対応する為のメモです※crosの設定を上に持ってこないと一部ヘッダが付与されない場合がある?
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ 'cros', 'throttle:60,1', 'bindings', ], ]; /** * The application's route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $routeMiddleware = [ 'cros' => \Barryvdh\Cors\HandleCors::class, 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, ];セッション共有
.envにSESSION_DOMAIN設定すればサブドメイン間でセッション共有可能
'''.enb
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_DOMAIN='.hoge.hoge'
'''
- 投稿日:2020-09-13T13:43:47+09:00
AndroidスマホにApacheとPHPとMySQLをインストールする
UerLandを使ってAndroidスマホにApacheとPHPとMySQLをインストールします。
UserLandでUbuntuのsshをインストールするとポート2022番号でログインをすることができます。
ssh USERNAME@192.168.xxx.xxx -p2022 ;ログインをしたらまずは最新にアップデート
sudo apt update ; sudo apt upgrade -y ; sudo apt install -y nano ;Apache2 PHP MySQLをインストール
sudo apt install apache2 php php-mysql mariadb-server ;Apacheの開放ポートを80から8080へ変更
emacs /etc/apache2/ports.conf ;下記修正
Listen 80 ↓ Listen 8080サービスとして起動(systemctrlは使用できないため)
service apache2 start ;他の端末からブラウザで
http://192.168.xxx.xxx:8080を開く。
/var/www/html/内のファイルにアクセスができます。
PHPの動作確認
mv /var/www/html/index.html /var/www/html/index.html.back ; nano /var/www/html/index.php ;index.phpに下記を記述
<?php phpinfo();保存
再び
http://192.168.xxx.xxx:8080を開くとphpの情報がズラリと出ます。
ワードプレスも行けそうです。
- 投稿日:2020-09-13T12:05:22+09:00
Stoplight Studioで作成したswagger.yamlを並び替えて見やすくするプログラムを作った
Swagger.yamlを作るのにstoplightのツールはとても便利なのですが、
生成されるファイルは、ツールで登録した順に記述されるので、後でSwagger.yamlそのものを、見た時に並び順がバラバラで見づらくなります。
そこで、APIやComponentを昇順に並び替えて、中の項目も同じ順で並び替えるプログラムを作りました。事前準備
yamlファイルの読み込み、書き出しにsymfony/yamlパッケージを使います。
composerを使ってインストールしてください。例:
composer.json{ "require": { "symfony/yaml": "*" } }
php composer install
使い方
以下のプログラムを、整形したいswaggerファイルを指定して実行するだけです。
指定したファイルの拡張子の手前に、_convertedとついたファイルが生成されます。convert_swagger.php<?php require 'vendor/autoload.php'; use Symfony\Component\Yaml\Yaml; // yamlファイルを読み込んでarray配列に変換する $file_name = $argv[1]; $content = file_get_contents($file_name); $yaml_array = Yaml::parse($content); // APIの並びをURLの昇順にする $paths = $yaml_array["paths"]; ksort($paths); $yaml_array["paths"] = $paths; // components schemasの並び順を昇順にする $schemas = []; if(array_key_exists("components", $yaml_array)){ $schemas = $yaml_array["components"]["schemas"]; ksort($schemas); } // APIの項目を並び替える foreach($paths as $key1 => $value1){ foreach($value1 as $key2 => $value2){ $item = []; $item["operationId"] = $value2["operationId"]; $item["tags"] = $value2["tags"]; $item["summary"] = $value2["summary"]; $item["description"] = $value2["description"]; $item["parameters"] = $value2["parameters"]; if(array_key_exists("requestBody", $value2)){ $item["requestBody"] = $value2["requestBody"]; unset($value2["requestBody"]); } $item["responses"] = $value2["responses"]; $yaml_array["paths"][$key1][$key2] = $item; } } // components schemasの項目を並び替える foreach($schemas as $key => $value){ $item = []; $item["title"] = $value["title"]; $item["description"] = $value["description"]; $item["type"] = $value["type"]; $item["properties"] = $value["properties"]; $item["required"] = $value["required"]; $yaml_array["components"]["schemas"][$key] = $item; } // 並び替えたデータをyaml形式に変換し、ファイルに出力する $file_name = preg_replace("/\.yaml$/", "_converted.yaml", $file_name); file_put_contents($file_name, Yaml::dump($yaml_array,99,2)); ?>実行例
php convert_swagger.php sample.v1.yaml
sample.v1_converted.yamlが生成されます。
- 投稿日:2020-09-13T10:32:55+09:00
PHPUnitのバージョンアップで使えなくなったgetMock()の置き換え法(草刈り)
環境
- php 5.6.21
- phpUnit 5.7.27
- Xdebug 2.4.0
前置き
たまたまPHPUnit5.7.27が入っている環境の触れる機会がありました。
この環境でテストを実行すると以下のように大量の警告が出てきて「何事だ!?」となったのが始まりです。
↑大量の警告が出て大草原になっています
この警告を消して(草刈りして)いきたいと思います。警告の内容
警告の内容は以下の通りです。
PHPUnit_Framework_TestCase::getMock() is deprecated, use PHPUnit_Framework_TestCase::createMock() or PHPUnit_Framework_TestCase::getMockBuilder() instead
getMock
は廃止予定だからcreateMock
かgetMockBuilder
に置き換えてねという内容です。getMock()の仕様
舞台裏では、getMock() メソッドが使われたときに PHPUnit が自動的に、求める振る舞いを実装した新たな PHP のクラスを生成しています。 生成されるテストダブルクラスの設定は、 getMock() メソッドのオプションの引数を使って行います。
デフォルトでは、指定したクラスのすべてのメソッドが単に NULL を返すだけのテストダブルとなります。返り値を変更するには、たとえば will($this->returnValue()) を使います。
オプションの第二パラメータを指定すると、その配列の中に含まれる名前のメソッドだけがテストダブルに置き換えらて、その他のメソッドはそのままとなります。パラメータに NULL を渡すと、どのメソッドも置き換えません。
オプションの第三パラメータには、元クラスのコンストラクタに渡すパラメータの配列を渡します (デフォルトでは、コンストラクタはダミー実装に置き換えられません)。
オプションの第四パラメータを使うと、生成されるテストダブルクラスのクラス名を指定することができます。
オプションの第五パラメータを使うと、元クラスのコンストラクタを呼び出さないようにすることができます。
オプションの第六パラメータを使うと、元クラスの clone コンストラクタを呼び出さないようにすることができます。
オプションの第七パラメータを使うと、テストダブルクラスの生成時に __autoload() を無効にすることができます。
https://phpunit.de/manual/3.7/ja/test-doubles.htmlこれを置き換えていきます!
getMockBuilderで置き換えていく!
仕様を読んで置き換えていくと以下のようになります。
getMock(hoge1,hoge2,hoge3,hoge4,hoge5,hoge6,hoge7); // 置き換え後 getMockBuilder(hoge1) ->setMethods(hoge2) // 置き換えたいメソッドを指定 ->setConstructorArgs(hoge3) // コンストラクタに渡す引数を指定 ->setMockClassName(hoge4) // 生成されるテストダブルクラスのクラス名を指定 ->disableOriginalConstructor(hoge5) // 元クラスのクローンコンストラクタを無効にする ->disableOriginalClone(hoge6) // 元クラスのクローンコンストラクタを無効にする ->disableAutoload(hoge7) // __autoload()を無効にする ->getMock(); // モックの取得今回は置き換えの該当箇所がとても多いので、
getMock
をオーバーライドする形で置き換えます。
適当な場所に以下のようなファイルを作成します。tests/TestAdapter.php<?php class TestAdapter extends PHPUnit_Framework_TestCase { public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true) { // モックの生成 $mockObject = $this->getMockBuilder($originalClassName); // 置き換えたいメソッドを指定。 if (!empty($methods)) { $mockObject = $mockObject->setMethods($methods); } // コンストラクタに渡す引数を指定 if (!empty($arguments)) { $mockObject = $mockObject->setConstructorArgs($arguments); } if ($mockClassName != '') { $mockObject = $mockObject->setMockClassName($mockClassName); } // 元クラスのクローンコンストラクタを無効にする if (!$callOriginalConstructor) { $mockObject = $mockObject->disableOriginalConstructor(); } // 元クラスのクローンコンストラクタを無効にする if (!$callOriginalClone) { $mockObject = $mockObject->disableOriginalClone(); } // __autoload()を無効にする if (!$callAutoload) { $mockObject = $mockObject->disableAutoload(); } // 生成 $mockObject = $mockObject->getMock(); return $mockObject; } }これを
init.php
で呼び出します。tests/init.phprequire_once dirname(__FILE__) . '/TestAdapter.php';// 適当な場所に追記してください。あとは各テストで
PHPUnit_Framework_TestCase
を呼び出していた箇所をTestAdapter
に変えていけばOKです!- class hogetest extends PHPUnit_Framework_TestCase + class hogetest extends TestAdapter置き換え後のテスト結果
きれいになりました!
- 投稿日:2020-09-13T10:11:31+09:00
PHPでWindows向けのCSVデータをLinuxサーバにて生成する。
手間だった為、関数を用意しておく。
生成するCSVデータ
- 文字コード = Shift-JIS
- 改行コード = ¥r¥n
- ¥r = キャリッジ・リターン(carriage return、復帰)
- ¥n = ライン・フィード(line feed、改行)
- 項目を囲む文字 = 「"」(ダブルコーテーション)
関数
/** * 二次元配列からWindows向けのCSVデータを生成する。 * * @param array $records * @param string $delimiter * @param string $enclosure * @param string $enclosure_escape * @param string $line_break * @param string $from_encoding * @param string $to_encoding * @param int $maxmemory * @return string */ function createWinCSV( $records, $delimiter=',', $enclosure='"', $enclosure_escape='""', $line_break="\r\n", $from_encoding='UTF-8', $to_encoding='SJIS-win', $maxmemory=5242880 ){ $fp = fopen("php://temp/maxmemory:" . $maxmemory, 'r+b'); $delimiter = $enclosure . $delimiter . $enclosure; foreach ($records as $record) { $line = $enclosure . implode($delimiter, array_map( function($val) use($enclosure, $enclosure_escape) {return str_replace($enclosure, $enclosure_escape, $val);}, $record)) . $enclosure . $line_break; fwrite($fp, $line); } rewind($fp); $tmp = stream_get_contents($fp); fclose($fp); return mb_convert_encoding($tmp, $to_encoding, $from_encoding); }使用例
$records = [ ['id', 'name', 'birthday', 'comment'], ['0001', '佐藤', '1980/01/02', 'Thanks!'], ['0002', '鈴木', '1990/03/04', 'Hello.'], ['0003', '田中', '2000/05/06', 'I say "Hello".'] ]; print(createWinCSV($records)); # "id","name","birthday","comment" # "0001","����","1980/01/02","Thanks!" # "0002","���","1990/03/04","Hello." # "0003","�c��","2000/05/06","I say ""Hello""."参考
生成したCSVデータをCSVファイルとしてダウンロードする箇所は、次のページを参考にさせて頂いた。
【PHP】【CakePHP】CSVダウンロード - Qiita備考
本記事はブログ「雑用エンジニアの技術ノート」からの移行記事です。先のブログは削除予定です。
- 投稿日:2020-09-13T08:49:51+09:00
Web系の定番ソフトウェアのバージョンを確認する。
次のコマンドを発行する。
CentOS
cat /etc/redhat-release
Apache
httpd -v
Java
java -version
Python
python --version python3 --versionPHP
php -v
WordPress
cat wordpress/wp-includes/version.php # $wp_versionの値を確認する。MySQL
-- MySQL接続後に次のSQL文を発行する。 select version();Oracle Database
-- OracleDB接続後に次のSQL文を発行する。 select * from v$version;備考
本記事はブログ「雑用エンジニアの技術ノート」からの移行記事です。先のブログは削除予定です。
- 投稿日:2020-09-13T01:51:01+09:00
Laravel8を試したら即効でエラー「Target class [〇〇〇Controller] does not exist.」が表示された
はじめに
最近になってLaravel8がリリースされたと聞いて、とりあえず動かしてみようと思ったら開始早々にエラーが発生しました。
web.php
でPostController
を呼び出す処理を書いたのに上記エラーが発生。Laravel6ではちゃんと呼び出せたのに
そのときのweb.php
はこちら。web.php<?php use Illuminate\Support\Facades\Route; Route::get('/', 'PostController@index');原因調査したら、どうやらLaravel8の変更点の一つである「
RouteServiceProvider.php
ファイルからデフォルトの名前空間を削除」したのが大きく関係していると判明!Laravel7.xのプロジェクトからLaravel8.xに移行した場合は、この変更点の影響は受けない。Laravel8で作成した新規プロジェクトは変更点を考慮する必要があるそうです。RouteServiceProvider.phpの変化
Laravel7までは、
RouteServiceProvider.php
には次のコードが含まれていました。RouteServiceProvider.phpprotected $namespace = 'App\Http\Controllers'; Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php'));webミドルウェアと
App\Http\Controllers
の名前空間を使用して、routes/web.php
にルートをロードするよう指示しています。web.php// Laravelは、App\Http\Controllers\PostControllerを検索します Route::get('/', 'PostController@index');
Laravel8では、$namespace変数が削除され、Route宣言が次のように変更されました。
RouteServiceProvider.phpRoute::middleware('web') ->group(base_path('routes/web.php'));
App\Http\Controllers
の名前空間を使用していないです。web.php// Laravelは、App\Http\Controllers内でコントローラーを検索しません Route::get('/', 'PostController@index');このあと、どう修正すればよいのか解決方法を3つご紹介します。
解決方法
RouteServiceProvider.php
で名前空間を手動で追加するweb.php
で完全な名前空間を使用するweb.php
でアクション構文を使用するRouteServiceProvider.phpで名前空間を手動で追加する
Laravel7.x以前と同じ方法です。
RouteServiceProvider.phpprotected $namespace = 'App\Http\Controllers'; //追加 public function boot() { $this->configureRateLimiting(); $this->routes(function () { Route::middleware('web') ->namespace($this->namespace) //追加 ->group(base_path('routes/web.php')); Route::prefix('api') ->middleware('api') ->namespace($this->namespace) //追加 ->group(base_path('routes/api.php')); }); }web.phpで完全な名前空間を使用する
コントローラーの名前の前に名前空間を追加します。
例として、app/Http/Controllers
フォルダ内のPostController
を呼び出したいときは、次の通り記載します。web.phpRoute::get('/', 'App\Http\Controllers\PostController@index');web.phpでアクション構文を使用する
web.phpuse Illuminate\Support\Facades\Route; use App\Http\Controllers\PostController; Route::get('/', [PostController::class, 'index']);配列で使用したいクラスとメソッドを指定します。
具体的に配列内の値は
PostsController :: class -> App \ Http \ Controllers \ PostsControllerを返している
index -> PostController.phpのindexメソッドを呼び出している終わりに
Laravel開発で初めて遭遇したエラーでしたので勉強になりました。
ただ、Laravel8の新機能・変更点を理解してから使用してみようと思いました。理解せず使用すると痛い目に遭いますね参考
- 投稿日:2020-09-13T00:24:03+09:00
Laravelでneo4jを使う④マイグレーション
事前準備
・app/database/labelsフォルダの作成
$ php artisan neo4j:make:migration create_race_label
$ php artisan neo4j:migrate
コマンド 説明 $label->unique('email') プロパティに一意の制約を追加する $label->dropUnique('email') プロパティから一意の制約を削除する $label->index('uuid') プロパティにインデックスを追加する $label->dropIndex('uuid') プロパティからインデックスを削除しています コマンド 説明