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

【PHP】session_start(): Failed to read session data: user (path: /var/lib/php/session) in ...が発生したときの対応

 はじめに セッションハンドラでセッション管理をしていたときにsession_start()を呼び出すと下記エラーが発生。 session_start(): Failed to read session data: user (path: /var/lib/php/session) in ... 本記事ではエラーの原因、解決方法を備考録としてまとめております。 原因 セッションハンドラ実装の流れ session_set_save_handler関数を定義 関数の説明は公式を参照 session_set_save_handler関数にSessionHandlerInterfaceインタフェースを実装したクラスのオブジェクトを渡す SessionHandlerInterfaceを実装するには、以下の6つのメソッドを実装する close(): bool destroy(string $sessionId): bool gc(int $lifetime): bool open(string $savePath, string $sessionName): bool read(string $sessionId): string write(string $sessionId, string $data): bool 今回のエラーの原因はFailed to read session data〜の通り、readメソッドの部分が該当していると読み取れる。公式のsession_start関数にてエラー文言について触れている部分がないか検索すると、下記内容が見つかる。 If you are using a custom session handler via session_set_save_handler() then calling session_start() in PHP 7.1 you might see an error like this: session_start(): Failed to read session data: user (path: /var/lib/php/session) in ... As of this writing, it seems to be happening in PHP 7.1, and things look OK in PHP7.0. It is also hard to track down because if a session already exists for this id (maybe created by an earlier version of PHP), it will not trigger this issue because the $session_data will not be null. The fix is simple... you just need to check for 'null' during your read function: <?php function read($id) { //... pull the data out of the DB, off the disk, memcache, etc $session_data = getSessionDataFromSomewhere($id); //check to see if $session_data is null before returning (CRITICAL) if(is_null($session_data)) { $session_data = ''; //use empty string instead of null! } return $session_data; } ?> どうやら、戻り値がnull今回のエラーが発生する模様。。  解決方法 先の検索結果を参考に、戻り値がnullかどうかをチェックしてnullの場合は空文字を返す。 //check to see if $session_data is null before returning (CRITICAL) if(is_null($session_data)) { $session_data = ''; //use empty string instead of null! } return $session_data; 終わりに readメソッドでDBの取得が0件の時に戻り値をnullにしていたため今回のエラーが発生しておりました。エラー事象を解決した後に、公式のreadメソッドの説明を眺めていたら、しっかり取得データがないときは空文字を返却するよう記載があった。。 read コールバックは、常にセッションエンコード (シリアライズ) された文字列を返さなければなりません。何もデータを読み込まなかった場合は空文字列を返します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

composer self-updateできない

はじめに 環境変数の設定中に、phpdotenvというライブラリを導入する際に、複数のエラーにハマったので、備忘録として残します。 現状① phpdotenv導入のために、下記コマンド入力後に、Composer2へアップデートして下さいとのエラーが出ている状況。 docker-compose exec app composer require vlucas/phpdotenv Warning from https://repo.packagist.org: You are using an outdated version of Composer. Composer 2 is now available and you should upgrade. See https://blog.packagist.com/deprecating-composer-1-support/ https://blog.packagist.com/deprecating-composer-1-support/を参照 対応① 素直にcomposerをアップデートするコマンドを入力 $ sudo composer self-update 現状② composerコマンドが使用できない現状。 composer: command not found 対応② /usr/local/bin/を確認。composerあるのにな・・・と思い、バージョンを確認してみるが、not found・・・。 $ composer --version zsh: command not found: composer composerを削除して、composerを再インストールしてみる。 $ sudo rm -rf /usr/local/bin/composer composer.pharを落としてくる $ sudo curl -s https://getcomposer.org/installer | php Password聞かれるので、入力する Password: All settings correct for using Composer Downloading... Composer (version 2.2.4) successfully installed to: /Users/〇〇/composer.phar Use it: php composer.phar composer.pharを移動する $ sudo mv composer.phar /usr/local/bin/composer composerのバージョンを確認してみる $ composer --version Composer version 2.2.4 2022-01-08 12:30:42 これでコマンドが使用できていますし、バージョンUPもできました! まとめ 1日に2回もcommand not foundを見るなんて・・・・と思い、備忘録として残しました。少しでも参考になると幸いです。 参考記事 PHP | Composer のバージョンを 2.x にバージョンアップする 「composer self-update」を実行するとエラー [Mac]composer: command not found 対処法
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

command not found:phpを解消する

はじめに phpのバージョンを確認するコマンドを入力した際にエラーにハマったので、備忘録として残します。 現状 php -v入力後に下記エラーが出ている現状。 $ php -v zsh: command not found: php 原因 パスの通し方が間違っていたのが原因でした。 対応 まずは、phpのパスを調べる。 brew --prefix php@7.4 私の環境では、usr/〇〇/opt/php@7.4なので/Users/ユーザー名/.zshrcを編集します。catコマンドを使用して、現在の設定を確認します。 cat ~/.zshrc viコマンドでパスを編集します。編集方法は、iを押して、インサートモードに入る。escを押して戻る。:wで書き込みをして、:qで終了する vi ~/.zshrc export PATH=(brew --prefix php@7.4で返ってきたパス)bin:$PATH 下記コマンドで、変更を反映させます。 source ~/.zshrc php -vコマンドを実行する。 PHP 7.4.27 (cli) (built: Dec 16 2021 18:14:46) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.27, Copyright (c), by Zend Technologies phpのコマンドが使用できるようになりました! まとめ command not foundってよくみるエラーなので、備忘録として残しました。 少しでも参考になると幸いです。 参考記事 sourceコマンドを誤って使ってしまいゾッとした話 bash: : command not found 〜どんなコマンドを打っても抜け出せない地獄〜
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

League/Csvで5C問題を回避してCSVを読む

PHPのCSV操作ライブラリLeague/Csvでは文字コードがShift-JISのCSVを読むことができますが、5C問題のためにフィールドがうまく区切られない場合があります。5C問題はShift-JIS固有の問題で、バックスラッシュとして解釈される0x5cが一部の文字コードの先頭に含まれることに起因する問題を指します。これを発生させる文字はいわゆるダメ文字として知られており、例として「貼」「表」「能」などが挙げられます。 この記事では、League/Csvを利用してCSVを読む際に5C問題を回避する方法について記します。記事中で利用するLeague/Csvのバージョンは9.8.0、PHPのバージョンは8.1.0となります。 フィールドをうまく区切れない例 読み込むCSVファイルが 文字コードがShift-JISである ダメ文字がエンクロージャの直前で用いられている の条件をすべて満たす場合にフィールドがうまく区切れない現象が発生します。具体的には次のようなCSVおよび読み込みの実装で再現できます。 data.csv "0160841","養蚕","ようさん","能代市","秋田県" "4370061","久能","くの","袋井市","静岡県" "9071542","西表","いりおもて","八重山郡竹富町","沖縄県" <?php use League\Csv\CharsetConverter; use League\Csv\Reader; $csv = Reader::createFromPath($path, 'r'); $encoder = (new CharsetConverter())->inputEncoding('SJIS'); $records = $encoder->convert($csv); $data = []; foreach ($records as $record) { $data[] = $record; } print_r($data); 出力結果 Array ( [0] => Array ( [0] => 0160841 [1] => 養蚕",ようさん" [2] => 能代市 [3] => 秋田県 ) [1] => Array ( [0] => 4370061 [1] => 久能",くの" [2] => 袋井市 [3] => 静岡県 ) [2] => Array ( [0] => 9071542 [1] => 西表",いりおもて" [2] => 八重山郡竹富町 [3] => 沖縄県 ) ) ここで「蚕」「能」「表」はいずれもダメ文字で、久能",くの"のように、きちんと区切られていないことが分かります。"能代市"のように、ダメ文字が含まれていてもエンクロージャの直前でない場合はフィールドは正常に区切られます。 回避方法1: エスケープ文字に\を利用しない場合 League/Csvではデフォルトのエスケープ文字が\です1。したがって、フィールドが区切られない原因としてダメ文字に含まれる0x5cが直後のエンクロージャーをエスケープしている、つまり"久能","くの"を"久能\","くの"と解釈していると考えられます。そこで、エスケープ文字を\以外のものにすることで回避します。 <?php use League\Csv\CharsetConverter; use League\Csv\Reader; $csv = Reader::createFromPath($path, 'r'); $csv->setEscape(''); // エスケープ文字を設定 $encoder = (new CharsetConverter())->inputEncoding('SJIS'); $records = $encoder->convert($csv); $data = []; foreach ($records as $record) { $data[] = $record; } フィールドをうまく区切れない例の実装に$csv->setEscape('')を追加し、エスケープ文字を空文字に設定しています。エスケープ文字を空文字にするとRFC4180に従った形式となり、"は""としてエスケープできます。 回避方法2: エスケープ文字に\を利用する場合 読み込むCSVで\をエスケープ文字に利用している場合は上記の方法は利用できません。その場合はCharsetConverterの代わりにmb_convert_encodingで文字コードの変換を行ったうえで読み込みます。 <?php use League\Csv\Reader; $data = mb_convert_encoding(file_get_contents('data.csv'), 'UTF-8', 'SJIS'); $csv = Reader::createFromString($data); $records = $csv->getRecords(); $data = []; foreach ($records as $record) { $data[] = $record; } CSVファイルの容量が大きい場合、この方法ではメモリ使用量が増えるため注意が必要です2。容量の大きいファイルを扱う場合はストリームフィルタを利用する方法があります3。また、エスケープ文字が削除されないSplFileObjectのバグも報告されており4、これを解決するためにもストリームフィルタが利用できます。 参考文献 PHPでLeague/CSVによるCSV(SJIS-win)の読み込み https://csv.thephpleague.com/9.0/connections/controls/#the-escape-character ↩ 容量の大きいCSVファイルの扱い (Shift-JIS) ↩ PHP: fgetcsvでもSJISのCSVをUTF-8として《安全》に読む方法(ストリームフィルタ使用) ↩ PHP bug: escape characters not stripped by SplFileObject:fgetcsv · Issue #149 · thephpleague/csv · GitHub ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL2(Ubuntu)でPHP + Apache環境を構築する①

WSL2(Ubuntu)を使用して、Windows上にLinuxの仮想環境を構築し、PHP + Apacheの開発環境を整えます。 本稿は2部構成となっております。第1部では、WSL2・Ubuntuをインストールして、Linux環境を構築するところまで進めます。 前提条件 Window10環境 当記事は2022年1月時点の情報に基づいて、執筆しています。WSL関連の情報は頻繁にアップデートされているようですので、実行前に公式ドキュメントを確認することをお勧めします。 公式ドキュメント : https://docs.microsoft.com/ja-jp/windows/wsl/install Windowsのバージョン確認 作業に入る前に、まずはWindowsのバージョンを確認しておきましょう。 Windowsキー + Rでファイル名を指定して実行画面を開きます。名前欄にwinverと入力してOKをクリックすると、Windowsのバージョン情報が確認できます。 ここでバージョンのビルドが 19041 以降であることを確認しておきましょう。19041 に満たない場合は、Windowsアップデートを行ってください。 WSL2のインストール スタートメニューからpowershellと検索し、Windows PowerShellを管理者として実行し、次のコマンドを入力します。 64ビット版のWindowsをお使いの方はpowershellで検索すると、無印(64ビット版)とx86(32ビット版)が出てきますが、無印のほうを使用してください。 PowerShell wsl --install インストールが正常に終了すると、PCを再起動するように促すメッセージが表示されるので、言われたとおりに再起動します。 Ubuntuのインストールと初期設定 Ubuntuのインストール Windowsを再起動すると、自動的にUbuntuがインストールされます。下記のような画面が表示されますので、インストール完了までしばらく待ちます。 ユーザー名とパスワードの設定 インストールが終わると、下記のようにユーザー名とパスワードを設定するよう求められます。任意のユーザー名とパスワードを入力します。 Ubuntu Enter new UNIX username: # 任意のユーザー名を入力 New password: # 任意のパスワードを入力 Retype new password: # パスワードを再度入力 パスワードを入力する際、セキュリティ上の観点からキーボードにタイプしても画面上には反映されませんが、きちんと入力できています。 最新版にアップデートする 下記コマンドを入力して、Ubuntuを最新版にアップデートしておきましょう。コマンド実行後、パスワードの入力を求められるので、先ほど設定したパスワードを入力します。 Ubuntu sudo apt update && sudo apt upgrade 日本語環境設定をする 必須ではありませんが、日本語環境設定をしておくと扱いやすいのでやっておきます。 まずは、タイムゾーン設定です。 Ubuntu sudo dpkg-reconfigure tzdata 実行すると下記のような画面が表示されるので、Asiaを選択してOk(Enterキー) ⇒ Tokyoを選択してOk(Enterキー)を入力します 次に言語設定です。 Ubuntu sudo apt install locales sudo apt install -y language-pack-ja sudo update-locale LANG=ja_JP.UTF-8 最後に、man(マニュアル)の日本語版を入れておきましょう。 Ubuntu sudo apt install -y man manpages-ja manpages-ja-dev ここまで完了したら、一旦Ubuntuの画面を終了し、スタートメニューからUbuntuを検索して再度立ち上げましょう。日本語の設定が反映されます。 動作の確認 きちんとWSL2でUbuntuを動かせているか確認しておきます。 もう一度Windows PowerShellを開いて、下記コマンドを実行します。 PowerShell wsl -l -v 下記のような表示が返ってきたら成功です。きちんと動作しています。 PowerShell NAME STATE VERSION * Ubuntu Running 2 WindowsのGUIでUbuntuを操作する CUIの操作に慣れてないうちは、UbuntuをGUIで操作したり確認したい場合もあるでしょう。WindowsのGUI画面からUbuntuの操作をする方法を解説します。 Windowsキー + Eでエクスプローラを開き、アドレスバーに\\wsl$\Ubuntu\home\{Ubuntuのユーザー名}と入力して、Enterを押します。そうすると、Ubuntuのホームディレクトリの中身をGUIで確認できます。ここからLinuxコマンドを使用せずに、ファイルを作成したり削除することもできます。 デスクトップにショートカットを作成しておくとよいでしょう。 まとめ ここまでの作業お疲れさまでした。第2部では、VScode、PHP、Appacheの導入を行っていきます。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL2(Ubuntu)でPHP + MySQL環境を構築する①

WSL2(Ubuntu)を使用して、Windows上にLinuxの仮想環境を構築し、PHP + MySQLの開発環境を整えます。 本稿は2部構成となっております。第1部では、WSL2・Ubuntuをインストールして、Linux環境を構築するところまで進めます。 前提条件 Window10環境 当記事は2022年1月時点の情報に基づいて、執筆しています。WSL関連の情報は頻繁にアップデートされているようですので、実行前に公式ドキュメントを確認することをお勧めします。 公式ドキュメント : https://docs.microsoft.com/ja-jp/windows/wsl/install Windowsのバージョン確認 作業に入る前に、まずはWindowsのバージョンを確認しておきましょう。 Windowsキー + Rでファイル名を指定して実行画面を開きます。名前欄にwinverと入力してOKをクリックすると、Windowsのバージョン情報が確認できます。 ここでバージョンのビルドが 19041 以降であることを確認しておきましょう。19041 に満たない場合は、Windowsアップデートを行ってください。 WSL2のインストール スタートメニューからpowershellと検索し、Windows PowerShellを管理者として実行し、次のコマンドを入力します。 64ビット版のWindowsをお使いの方はpowershellで検索すると、無印(64ビット版)とx86(32ビット版)が出てきますが、無印のほうを使用してください。 PowerShell wsl --install インストールが正常に終了すると、PCを再起動するように促すメッセージが表示されますので、言われたとおりに再起動します。 Ubuntuのインストールと初期設定 Ubuntuのインストール Windowsを再起動すると、自動的にUbuntuがインストールされます。下記のような画面が表示されますので、インストール完了までしばらく待ちます。 ユーザー名とパスワードの設定 インストールが終わると、下記のようにユーザー名とパスワードを設定するよう求められます。任意のユーザー名とパスワードを入力します。 Ubuntu Enter new UNIX username: # 任意のユーザー名を入力 New password: # 任意のパスワードを入力 Retype new password: # パスワードを再度入力 パスワードを入力する際、セキュリティ上の観点からキーボードにタイプしても画面上には反映されませんが、きちんと入力できています。 最新版にアップデートする 下記コマンドを入力して、Ubuntuを最新版にアップデートしておきましょう。 Ubuntu sudo apt update && sudo apt upgrade 日本語環境設定をする 必須ではありませんが、日本語環境設定をしておくと扱いやすいのでやっておきます。 まずは、タイムゾーン設定です。 Ubuntu sudo dpkg-reconfigure tzdata 実行すると下記のような画面が表示されるので、Asiaを選択してOk(Enterキー) ⇒ Tokyoを選択してOk(Enterキー)を入力します 次に言語設定です。 Ubuntu sudo apt install locales sudo apt install -y language-pack-ja sudo update-locale LANG=ja_JP.UTF-8 最後に、man(マニュアルのようなもの)の日本語版を入れておきましょう。 Ubuntu sudo apt install -y man manpages-ja manpages-ja-dev ここまで完了したら、一旦Ubuntuの画面を終了し、スタートメニューからUbuntuを検索して再度立ち上げましょう。日本語の設定が反映されます。 動作の確認 きちんとWSL2でUbuntuを動かせているか確認しておきます。 もう一度Windows PowerShellを開いて、下記コマンドを実行します。 PowerShell wsl -l -v 下記のような表示が返ってきたら成功です。きちんと動作しています。 PowerShell NAME STATE VERSION * Ubuntu Running 2 WindowsのGUIでUbuntuを操作する CUIの操作に慣れてないうちは、UbuntuをGUIで操作したり確認したい場合もあるでしょう。WindowsのGUI画面からUbuntuの操作をする方法を解説します。 Windowsキー + Eでエクスプローラを開き、アドレスバーに\\wsl$\Ubuntu\home\{Ubuntuのユーザー名}と入力して、Enterを押します。そうすると、Ubuntuのホームディレクトリの中身をGUIで確認できます。ここからLinuxコマンドを使用せずに、ファイルを作成したり削除することもできます。 デスクトップにショートカットを作成しておくとよいでしょう。 まとめ ここまでの作業お疲れさまでした。第2部では、VScode、PHP、MySQL、Appacheの導入をしていきたいと思います。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPで発生したエラーを画面に出力する方法

PHPのエラーをブラウザに表示させる方法 sudo vi /etc/php.ini 「/display」で検索 「エラーをHTML出力の一部として画面に出力するかどうか」の設定。OffをOnに変更。 display_errors = Off → display_errors = On 「display_errorsをOnにしても、自分で書いた<??>内のプログラムエラーしか表示しませんよ」という設定。OffをOnに変更。 display_startup_errors = Off → display_startup_errors = On
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECCUBEをdockerで動かす

ECCUBEを触りたくてdocker環境で動かすことにしました。 所々一筋縄ではいかなかったのでまとめました。 1.gitから落とす リポジトリURLからブランチ(tags)を確認して、実行するバージョンをローカルに落とす。 ECCUBEリポジトリのURL https://github.com/EC-CUBE/ec-cube.git ブランチの指定方法 git clone -b ブランチ名 https://リポジトリのURL (例)4.0.5の環境を利用する場合のコマンド git clone -b 4.0.5 https://github.com/EC-CUBE/ec-cube.git 2.docker-compose.ymlを修正する ・MySQLを利用したいので、Postgresをコメントアウト ・SSL利用しないのでコメントアウト ・動作が重くなるのでcachedをコメントアウト ・phpmyadminを利用するので追記 docker-compose.ymlサンプルファイル version: "3" networks: backend: driver: bridge volumes: # pg-database: # driver: local mysql-database: driver: local mailcatcher-data: driver: local ### ignore folder volume ##### var: driver: local vendor: driver: local services: ### ECCube4 ################################## ec-cube: build: context: . args: # ビルド時のECCubeインストールスクリプトをスキップする場合にtrueを指定する。 # ビルド時点でDBサーバの起動や接続が出来ない、という場合等にエラーとなるため。 SKIP_INSTALL_SCRIPT_ON_DOCKER_BUILD: "true" ports: - 8080:80 # - 4430:443 volumes: # - ".:/var/www/html:cached" ### 同期対象からコストの重いフォルダを除外 ##################### - "var:/var/www/html/var" - "vendor:/var/www/html/vendor" networks: - backend ### Postgres ################################ # postgres: # image: postgres:10 # environment: # - POSTGRES_DB=eccubedb # - POSTGRES_USER=dbuser # - POSTGRES_PASSWORD=secret # ports: # - 15432:5432 # volumes: # - pg-database:/var/lib/postgresql/data # networks: # - backend ### MySQL ################################## mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: eccubedb MYSQL_USER: dbuser MYSQL_PASSWORD: secret volumes: - mysql-database:/var/lib/mysql ports: - 13306:3306 networks: - backend restart: always ### phpmyadmin ################################## phpmyadmin: image: phpmyadmin/phpmyadmin links: - mysql:mysql volumes: - ./phpmyadmin/sessions:/sessions ports: - 4040:80 environment: - PMA_ARBITRARY=1 - PMA_HOST=mysql - PMA_USER=root - PMA_PASSWORD=root restart: always depends_on: - mysql networks: - backend ### Mailcatcher ################################## mailcatcher: image: schickling/mailcatcher ports: - "1080:1080" - "1025:1025" networks: - backend 3.Dockerfileを修正する ・composerを最新にすると動かなくなるのでバージョンを指定する。 Dockerfileの抜粋 RUN curl -sS https://getcomposer.org/installer \ | php \ && mv composer.phar /usr/bin/composer \ <font color="Red">&& composer selfupdate --1 \\</font> && composer config -g repos.packagist composer https://packagist.jp \ && composer global require hirak/prestissimo \ && chown www-data:www-data /var/www \ && mkdir -p \${APACHE_DOCUMENT_ROOT}/var \ && chown -R www-data:www-data \${APACHE_DOCUMENT_ROOT} \ && find ${APACHE_DOCUMENT_ROOT} -type d -print0 \ | xargs -0 chmod g+s \ ; 4.docker-composeコマンドの実行 コンテナの作成と開始 docker-compose up -d ECCUBEのインストール docker-compose exec -u www-data ec-cube bin/console eccube:install DBの設定 ※MySQLの場合以下を入力する。 Database Url [sqlite:///var/eccube.db]: mysql://dbuser:secret@mysql/eccubedb 以降Enter押下で完了 Mailer Url [null://localhost]: (Enter押下) Auth Magic [ランダム値]: (Enter押下) Is it OK? (yes/no) [yes]: (Enter押下) 6.サイトへアクセスする メインページ http://localhost:8080/ 管理者ページ[ID_admin][pass_password] http://localhost:8080/admin 『設定→システム設定→システム情報』で想定のバージョンがインストールされていることを確認する。 phpMyadmin http://localhost:4040/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

phpenv update でPHPの最新のバージョンが反映されない

$ phpenv install --list PHP8系が一覧にない $ phpenv update error: Your local changes to the following files would be overwritten by merge: share/php-build/default_configure_options Please commit your changes or stash them before you merge. Aborting エラーがでた。 以下のファイルをgitでcommitかスタッシュすればいいらしい。 面倒なので、default_configure_optionsのファイル名を変更(バックアップ) /Users/[ユーザ名]/.anyenv/envs/phpenv/plugins/php-build/share/php-build/default_configure_options $ phpenv update $ phpenv install --list PHP8系がインストールリストに表示された!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む