- 投稿日:2021-01-07T21:59:54+09:00
[EC-CUBE4]serviceファイル内でユーザのログイン状態を判別する方法
環境
EC-CUBE 4.0.5
symfony 3.4.42
php 7.3実行方法
// appを取得 $app = \Eccube\Application::getInstance(); // user情報を取得 $user = $app['user']; // ゲストユーザは"anon."が格納される if ($user != "anon.") { // 会員限定で行いたい処理 }これでログイン状態のユーザ(会員)を判別して処理を行えるうようになります。
参考に
isGranted('ROLE_USER')は使えない
こちらはAbstractControllerを継承しているController内でしか使えないです。
twig内で使うようなis_granted('ROLE_USER')
も使えません。他の実行例
こちらの記事にある
$this->app->user()
を使って取れる場合もあるようですが、私の環境では取れませんでした。
- 投稿日:2021-01-07T21:21:22+09:00
LaravelのPaginateでエラーが出たワケ
はじめに
初めてLaravelを触ってみました。プログラミング初心者らしすぎる凡ミスですが、記録的として残したいと思います。
環境
PHP 7.4
Laravel 6.20.8エラー内容
BadMethodCallException Call to undefined method App\XXX(model)::links() (View: /work/resources/views/XXX.blade.php)Paginateメソッドについて
Laravelにはページネーションがデフォルトで備わっています。
例えばUserController$users = User::orderBy('created_at', 'desc')->paginate(10); return view('user.index', ['users' => $users ]);users.blade.php@foreach($users as $user) {{ $user->name }} @endforeach {{ $users->links() }}これだけで、10件ごとにユーザー名が表示されるページネーションが簡単にできます。
今回のエラーの原因
Laravelでは、テーブル名を複数形、モデルを単数形にするというルールがありますが、今回私はどうしてもinfoという不可算名詞を使用したかったため、任意の名前でテーブル名を設定しました。
ですので、viewのforeachをこれまで書いていたものと同様、Laravelに頼りすぎて何も考えず下記のように書きました。example.blade.php@foreach($info as $info) {{ $info->name }} @endforeach {{ $info->links() }}すると先程のエラー。
変数がオーバーライドされるので、当たり前ですね...下記のように変更(例)しました。example.blade.php@foreach($info as $information) {{ $information->name }} @endforeach {{ $info->links() }}無事ページネーションができました。
おわりに
恥ずかしながらLaravelの便利さ故に詰まってしまいました。自分で任意の名前でテーブル名を設定できますが、できれば変なところで詰まりたくないので、Laravelではできるだけ命名規則に従っておこうと思います。
参考
- 投稿日:2021-01-07T18:13:40+09:00
『アウトプット』の重要性
・記事の概要
webエンジニアとして活動したく、現在独学でPHPの学習に取り組んでいます。
PHPを用いたWebアプリケーション開発経験を積んでいきたいので、
効率的な学習のためにもインプット、アウトプット、フィードバックを繰り返していくためにこの場をかりていこうと思います。ショッピングサイトやチケット購入サイトを利用することが多く、自分でもECサイト関連を作ってみたいと思ったので
ポートフォリオを作成の記録を残していこうと思います。①スペック
言語:PHP 7.2.24
DBMS:MySQL
CSSフレームワーク:milligram
開発環境:macOS Catalina 10.15.6、Apache 2.4.46
バージョン管理:Git 2.21.0
本番環境:Heroku
②Webアプリケーションの機能
公演のチケットを購入することができる。
データベース図は後ほど。
- 投稿日:2021-01-07T18:05:42+09:00
PHP 0を使って桁数を揃える
- 投稿日:2021-01-07T17:46:39+09:00
PHP8にアップデートしたら、laravelでMethod ReflectionParameter::getClass() is deprecated in ... エラーが出た話
使用していたバージョン
Laravel Framework 7.30.1
PHP 8.0.0エラー発生時
laravelでいつものように
php artisan コマンド
を使ったが、Method ReflectionParameter::getClass() is deprecated in ...長ったらしい文が出てきて、コマンドが使えない。
参考サイトによるとphp8で推奨されていないらしい、、、。
解決方法
- composer.jsonファイルのphpのバージョンを変更 例えば
php:^7.2.5 => php:^8.0
- コマンドで
composer update
を実行 で解決します。** また、バージョン変更により本番環境でがシステムが動かなくなる可能性があるので、
念のためphp:^7.2.5 => php:^8.0 ではなく php:^7.2.5|^8.0上記のように書き換えるといいです。
参考サイト
- 投稿日:2021-01-07T15:59:44+09:00
サーバーにruby、クライアントにPHPでgRPCを頑張る
はじめに
google謹製のRPCフレームワークであるgRPCを使って、サーバーにruby、クライアントにPHPを使って、異なる言語間を共通のI/FでAPI通信してみたいと思います。
異なる言語間としているのはgRPCのメリットであるIDL定義によるI/Fの共通化の醍醐味を味わってみたいというより、PHPでgRPCサーバの構築ができないという現実に対する条件反射のようなものですが、結果的に醍醐味もやってくるので、味わってみたいと思います。
クライアントにPHPを使う場合、サーバー側はどうもgoで紹介しているところが多いので、ここではrubyを使ってみます(はい、go知らないの確定)。
概要はここで書くまでもないので、さっそく。
ここではAPIとして、ドメインを指定すると有効期限を取ってくる、というものを書いてみます。INPUT: FQDN
OUTPUT: yyyy/mm/dd hh:ii:ssAPI(gRPC): 定義したI/Oで共通I/Fを用意
クライアント(PHP): サーバを通じてAPIにFQDNをリクエスト
サーバ(ruby): クライアントからリクエストされたFQDNからSSL証明書の有効期限を調べてAPI経由で日付をレスポンス事前作業
pecl install grpc pecl install protobuf vi (略)/php.ini extension=grpc.so extension=protobuf.so gem install grpc gem install grpc-tools mkdir ~/projects/grpc_trial/ cd ~/projects/grpc_trial/ composer require grpc/grpc composer require google/protobuf mkdir {protos,php,ruby}実作業
vi protos/checkexpires.proto (後述) grpc_tools_ruby_protoc -I ./protos --ruby_out=./ruby --grpc_out=./ruby ./protos/checkexpires.proto ls ruby/ | grep checkexpires checkexpires_pb.rb checkexpires_services_pb.rb protoc --proto_path=./protos --php_out=./php --grpc_out=./php ./protos/checkexpires.proto --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin ls php/Checkexpires/ CheckReply.php CheckRequest.php GetSslClient.php vi checkexpires.rb (後述) vi checkexpires.php (後述) ruby ./checkexpires.rb & php ./checkexpires.php php checkexpires.php example.com 2021/12/25 23:59:59checkexpires.protosyntax = "proto3"; package checkexpires; import "google/protobuf/timestamp.proto"; service GetSsl { rpc getExpire (CheckRequest) returns (CheckReply) {} } message CheckRequest { string fqdn = 1; } message CheckReply { google.protobuf.Timestamp timestamp = 1; }checkexpires.rbthis_dir = File.expand_path(File.dirname(__FILE__)) lib_dir = File.join(this_dir, 'ruby') $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'time' require 'grpc' require 'checkexpires_services_pb' class CheckexpiresServer < Checkexpires::GetSsl::Service def get_expire(check_req, _unused_call) end_at = `openssl s_client -connect #{check_req.fqdn}:443 </dev/null 2>/dev/null|openssl x509 -text | grep "Not After"` end_at = end_at.split(' : ').pop end_at = end_at.gsub("\n", '') end_at = Time.parse(end_at).to_i end_at = Time.at(end_at) Checkexpires::CheckReply.new(timestamp: end_at) end end def main s = GRPC::RpcServer.new s.add_http2_port('localhost:50051', :this_port_is_insecure) s.handle(CheckexpiresServer) s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT']) end maincheckexpires.php<?php require dirname(__FILE__).'/vendor/autoload.php'; require dirname(__FILE__).'/php/Checkexpires/GetSslClient.php'; require dirname(__FILE__).'/php/Checkexpires/CheckReply.php'; require dirname(__FILE__).'/php/Checkexpires/CheckRequest.php'; require dirname(__FILE__).'/php/GPBMetadata/Checkexpires.php'; $server = 'localhost:50051'; //checkexpires.rb if (is_null($argv[1] ?? null)) { echo "need to input fqdn\n"; exit(1); } try { $client = new Checkexpires\GetSslClient($server, [ 'credentials' => Grpc\ChannelCredentials::createInsecure(), ]); $request = new Checkexpires\CheckRequest(); $request->setFqdn($argv[1]); list($reply, $status) = $client->getExpire($request)->wait(); if (($status->code ?? null) === 0) { $ts = $reply->getTimestamp()->getSeconds(); echo date('Y/m/d H:i:s', $ts); exit(0); } } catch (Exception $e) { echo $e->getMessage(); exit(1); }補足
せっかく異なる言語で共通I/Fを定義しているのですから、それぞれのコンパイラも一個に共通化してしまいましょう。
vi ~/.bashrc function protoc2() { grpc_tools_ruby_protoc -I ./protos --ruby_out=./ruby --grpc_out=./ruby ./protos/$@ && protoc --proto_path=./protos --php_out=./php --grpc_out=./php ./protos/$@ --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin } . ~/.bashrc cd ~/projects/grpc_trial/ protoc2 checkexpires.protoこれで、ひとつのprotoファイルでrubyとPHPそれぞれの共通I/Fが準備できました。
あとはクライアント側とサーバ側にそれぞれ固有な処理を書いていけばいい感じですね。
頑張れそうです。
- 投稿日:2021-01-07T15:41:31+09:00
Eloquentのall()ってなんなの? いきなりget()しちゃダメなの?
はじめに
LaravelでDBからデータを取り出す処理を書いているときに、大体
all()
ってやるじゃないですか。$hoges = Hoge::all()で、自分で書いておきながら「あれ? 全件取り出しの時
all()
って書いたのなにげに初めてじゃね?」って思ったんですね。実際、他のところではいきなりget()
してました。$fugas = Fuga::get();で、この2つ、同じ動きをするわけなんですが、何が違うんじゃ? と思った次第です。
all()
のコードを見てみよう公式ドキュメント見ても何がどう違うのか書いてはいなかったので、コードを見てみることにしました。
vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(454-465)/** * Get all of the models from the database. * * @param array|mixed $columns * @return \Illuminate\Database\Eloquent\Collection|static[] */ public static function all($columns = ['*']) { return static::query()->get( is_array($columns) ? $columns : func_get_args() ); }どうも、普通に
get()
を呼んでいるだけのようです。
ただ、違うところは取得するカラムを引数で指定できるようになっているのですが、配列、もしくは可変長で取れる様になっているところみたいです。つまり、
$hoges = Hoge::all(['id', 'updated_at']);$hoges = Hoge::all('id', 'updated_at');は同じ動きをするってことですね。
get()
の場合は引数が1つの配列、もしくは文字列しか取れないので動かない例$hoges = Hoge::get('id', 'updated_at');これは動きません。
結論
- いきなり
get()
でも良さそう- 全件取得してるよ!ってのを明示的にしたければ
all()
を使う感じかな?
- 投稿日:2021-01-07T15:24:34+09:00
テスト投稿
テスト投稿
エンジニアを目指して
これからがんばります!
phpのインストール時のエラー
Error: The following formula cannot be installed from bottle and must be built from source. python@3.9 Install the Command Line Tools: xcode-select --installと出た。xcodeってなんだっけと思いながら
xcode-select --installを実行するもエラー。
そういえばPCの容量一杯になったときにアプリ消したか?覚えてないけどとにかくxcodeを入れようとするも容量不足で入れられず。
- 投稿日:2021-01-07T14:39:18+09:00
XAMPPでPHP8からPHP7へバージョンを下げる
XAMPPでPHP8からPHP7へバージョンを下げる
使用環境
- XAMPP 8.0 (PHP 8.0)
- windows10
背景
PHP7で開発していたLaravelアプリを別のPCで(PHP8)でも開こうと思ったら開けない!composer installがエラーになった。どうやらPHPのバージョンが違うぞ!と怒られたっぽい。ということでPHPをダウングレードすることにした。
XAMPPのApacheは消しておく
起動したまま操作しない方が良いみたい。
PHP7をダウンロードする
公式ページからPHP7をダウンロードする。今回、使用したのはVC15 x64 Thread Safe (2021-Jan-05 18:10:24)というファイル。
PHPダウンロードXAMPP内のPHPディレクトリをバックアップする
コピーでもOKなのですが、私はディレクトリ名をPHP → PHP8に変更した。
ダウンロードしたPHP7のディレクトリをPHPディレクトリとしてXAMPPディレクトリ内に移動
PHPディレクトリを新しく作って、その中に解凍したPHP7関連のファイルを全て放り込む。
PHP8で使用していたphp.iniをPHP7(PHPディレクトリ)にコピー
コピーしてそのまま使用。
ApacheのPHP設定を編集する
C:\xampp\apache\conf\extra\httpd-xampp.conf
内のPHP8と書かれているところを全てPHP7に変換。Apacheを起動
と思ったら、Apacheが起動しない!!!!
シャットダウン時に予期せぬエラーが発生した...みたいなことが書いてある!?
嫌な予感。MySQLが起動しないパターンでXAMPPを再インストールした過去があるのですごく嫌な予感。PHPのバージョン確認してみる
コマンドプロンプトで
php -v
を入力してみる。
エラーが発生。なんかファイルが無いっぽいことをいってる。PHP Warning: Cannot open 'C:\xampp\php\extras\browscap.ini' for reading in Unkno wn on line 0 Warning: Cannot open 'C:\xampp\php\extras\browscap.ini' for reading in Unknown on line 0 PHP Fatal error: Unable to start standard module in Unknown on line 0 Fatal error: Unable to start standard module in Unknown on line 0よくわからないけどPHP8のディレクトリに
xampp\php\extras\browscap.ini
があったのでコピーしてPHP7のxampp\php\extras
に置いてみた。もう一度バージョン確認
XAMPPのshellを起動して
php -v
と入力すると、きちんとPHP8からPHP7にバージョンが変わっている。さぁ、Apacheの起動だ
と思ったら、再度エラー。起動しない。
調べていくとコンパイラとか違ったら設定ファイルとか使いまわせないみたいなことが出てきた。
さらに調べてみるとどうやらSAPIモジュールというものが変更されているらしい。Apache2Handler
PHP モジュールの名前が php7_module から php_module に変更されました。
PHP公式ドキュメントということで
xampp\apache\conf\extra\http-xampp.conf
内のphp_moduleと書かれているところをphp7_moduleに変更。全部で4か所あった。正直、どれが作用しているのかはわからない。
3度目の正直、Apacheの起動
今回は無事、起動できた。
- 投稿日:2021-01-07T10:48:04+09:00
xdebug version 3になって動かなくなった
はじめに
新年になったので、開発環境のDockerをビルドし直したら、xdebugでのステップ実行ができなくなった。
調べてみると、xdebugのVersion3になって設定項目名が変更されてしまったため、以前の設定が無効になってしまったのが原因でした。TL;DR
以下の設定で動きました。
ちなみにデバッガ(IDE=phpstorm, vscode)の方の待受ポートは9003に合わせる必要があります。xdebug.log=/tmp/xdebug.log xdebug.mode=develop, debug xdebug.start_with_request=yes xdebug.client_host=host.docker.internal xdebug.client_port=9003 zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20170718/xdebug.sov2時代の設定
たぶん、こんな設定がインターネットで検索するとでてくると思います。こちらはversion2までの設定になります。
xdebug.remote_enable=1 xdebug.remote_autostart=1 xdebug.remote_port=9003 xdebug.remote_host="host.docker.internal" xdebug.remote_connect_back = 0 xdebug.remote_log=/tmp/xdebug.log zend_extension=xdebug.soxdebugのバージョン確認方法
php -v
とするとwith Xdebug v3.0.2
という風に表示されます。root@57b67435355c:/# php -v Cannot load Xdebug - it was already loaded PHP 7.2.33 (cli) (built: Sep 10 2020 15:18:34) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Xdebug v3.0.2, Copyright (c) 2002-2021, by Derick Rethans動作確認(phpstorm)
phpstormを使っているので、xdebugの動作確認になります。
以下の画像中の矢印で示しているデバッグポートですが、もともと9000, 90003
と書いてありましたが、③の検証を実行したところ、9003
にするように指示があったので変更しています。画像の中では、
xdebug.mode
がdebugじゃないと警告がでていますが、公式ドキュメントには、以下のように複数設定が有効なようです。実際、ステップ実行は実現できました。参考文献
公式サイト一択じゃないかな。。。。
- 投稿日:2021-01-07T05:25:43+09:00
初心者がLaravelでアプリをつくるまで
プログラミングスクールに通い始めて2ヶ月、、
あと1ヶ月で予定の3ヶ月を終えてしまうけど、全然ポートフォリオに使う予定のアプリが完成しない、、
とりあえず、全然連絡の取れなかったメンターの方を変更していただいてようやく方向性が定まってきた。とりあえず、つくってみるアプリは前々から少し考えていた、アンケートを投稿できるモノにした。
あまり難しそうなものを考えると心が折れそうなので、、内容としては、登録してくれたユーザが誰でもアンケートを投稿できて、他のユーザに回答してもらえて回答の集計を取れるようなものにしようかと、、
最初はとりあえず型だけつくって、後から時間があれば色々な機能を搭載していければいいかなってくらいです。まず言われた通り、基本設計とテーブル定義を調べながらやってみたけど、やり方が全然わからないのでとりあえずシートに書いてみました。
きっと間違いと足りない部分が多すぎると思うので、明日のメンタリング教えてもらおう、、
コードをこれから書いていくのですが、何から書き始めていいかさっぱりなのでスクールのカリキュラムを真似しながら1つずつ書いて行きます、、
頭の中では、このページのこの部分を押すとここに飛んで、あのボタンを押すとこうなってと、イメージはあるのですが、、
それを、紙にペンで書いていいなら今日中に終わるのに、コードでそれを表現するには初心者の自分からすれば莫大な時間がかかりそうです、、Qiita書いてて気が付くともう朝方なので、また明日からがんばります!
- 投稿日:2021-01-07T01:55:36+09:00
PHPのSJIS系文字コードを表にしてみた
はじめに
※ 本記事ではShift_JISを拡張した文字コードをSJIS系文字コードと記載しています。
Shift_JIS、Shift-JIS、SJIS、SJIS-win、CP932、MS932、Windows-31J、MS_Kanjiなどなど、、、
SJIS系文字コードってたくさんありますよね。
「Shift_JISでcsv下さい」って言われたからShift_JISに変換したら「髙」が〜「ハイフン」が〜と言われたことある方は少なくないと思います。サポートされる文字エンコーディングに記載されている中でよく使用するSJIS系の文字コードは、SJIS、SJIS-win、CP932の3種類だと思います。
サポートされるエンコーディングの概要のShift_JISの説明と注記に「IANA の定義によると、Shift_JIS のコードセットは IBM932 / CP932 とは微妙に異なります。」「CP932 コードマップを使用するには、代わりに SJIS-WIN を使用してください。」と記載されているため今までこのように考えていたんですが、実際は少し違うようです。
エンコーディング名 間違った解釈 SJIS Shift_JIS CP932 Windows-31J? SJIS-win NEC拡張のCP932? しかもサポートされる文字エンコーディングに記載されていない文字コードでも実際には指定することができます。
下記は全てError、Warning、Noticeが出ることなく変換できます。<?php mb_convert_encoding('テスト', 'SJIS'); mb_convert_encoding('テスト', 'SHIFT-JIS'); mb_convert_encoding('テスト', 'Shift_JIS'); mb_convert_encoding('テスト', 'CP932'); mb_convert_encoding('テスト', 'MS932'); mb_convert_encoding('テスト', 'MS_Kanji'); mb_convert_encoding('テスト', 'Windows-31J'); mb_convert_encoding('テスト', 'SJIS-win');どれが同じでどれが違う文字コードなのか、、、
このモヤモヤを解消するため、ソースコードを読んで表にまとめてみました。エンコーディングとエイリアスの表
mime_nameがShift_JISで登録されている文字コードを全て羅列しています。
エンコーディング名 エイリアス SJIS x-sjis, SHIFT-JIS CP932 MS932, Windows-31J, MS_Kanji SJIS-win SJIS-open, SJIS-ms SJIS-2004 SJIS2004, Shift_JIS-2004 SJIS-mac MacJapanese, x-Mac-Japanese SJIS-Mobile#DOCOMO SJIS-DOCOMO, shift_jis-imode, x-sjis-emoji-docomo SJIS-Mobile#KDDI SJIS-KDDI, shift_jis-kddi, x-sjis-emoji-kddi SJIS-Mobile#SOFTBANK SJIS-SOFTBANK, shift_jis-softbank, x-sjis-emoji-softbank エイリアスにShift_JISが登録されている文字コードはなかったんですが、実際にファイル出力してみたところSJISと同じっぽいです。
UTF-8環境で実行しているためか、CP932とSJIS-winで文字化けする文字に違いはありませんでした。$file = fopen('test.txt', 'w'); fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SJIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SHIFT-JIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'Shift_JIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'CP932')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'MS932')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SJIS-win')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'Windows-31J')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'MS_Kanji')); #=> 髙閒ー--㌢㏍? fclose($file);まとめ
UTF-8からの変換であれば、SJIS or CP932の2択で良さそうです。
Shift_JISのエイリアスであるはずのMS_Kanjiが、PHPではCP932のエイリアスとして登録されているのは不思議な感じがしました。結局SJIS-winが何を指しているのかはよくわかりませんでした。
そのうち「依存する文字集合」を確認して追記しようと思います。
- 投稿日:2021-01-07T01:55:36+09:00
PHPのSJIS系文字エンコーディングとエイリアスを表にまとめてみた
はじめに
※ 本記事ではShift_JISを拡張した文字エンコーディングをSJIS系文字エンコーディングと記載しています。
Shift_JIS、Shift-JIS、SJIS、SJIS-win、CP932、MS932、Windows-31J、MS_Kanjiなどなど、、、
SJIS系文字エンコーディングってたくさんありますよね。
「Shift_JISでcsv下さい」って言われたからShift_JISに変換したら「髙」が〜「ハイフン」が〜と言われたことある方は少なくないと思います。サポートされる文字エンコーディングに記載されている中でよく使用するSJIS系文字エンコーディングは、SJIS、SJIS-win、CP932の3種類だと思います。
サポートされるエンコーディングの概要のShift_JISの説明と注記に「IANA の定義によると、Shift_JIS のコードセットは IBM932 / CP932 とは微妙に異なります。」「CP932 コードマップを使用するには、代わりに SJIS-WIN を使用してください。」と記載されているため今までこのように考えていたんですが、実際は少し違うようです。
エンコーディング名 間違った解釈 SJIS Shift_JIS CP932 Windows-31J? SJIS-win NEC拡張のCP932? しかもサポートされる文字エンコーディングに記載されていない文字エンコーディングでも実際には指定することができます。
下記は全てError、Warning、Noticeが出ることなく変換できます。<?php mb_convert_encoding('テスト', 'SJIS'); mb_convert_encoding('テスト', 'SHIFT-JIS'); mb_convert_encoding('テスト', 'Shift_JIS'); mb_convert_encoding('テスト', 'CP932'); mb_convert_encoding('テスト', 'MS932'); mb_convert_encoding('テスト', 'MS_Kanji'); mb_convert_encoding('テスト', 'Windows-31J'); mb_convert_encoding('テスト', 'SJIS-win');どれが同じでどれが違う文字エンコーディングなのか、、、
このモヤモヤを解消するため、ソースコードを読んで表にまとめてみました。エンコーディングとエイリアスの表
mime_nameがShift_JISで登録されている文字エンコーディングを全て羅列しています。
エンコーディング名 エイリアス SJIS x-sjis, SHIFT-JIS CP932 MS932, Windows-31J, MS_Kanji SJIS-win SJIS-open, SJIS-ms SJIS-2004 SJIS2004, Shift_JIS-2004 SJIS-mac MacJapanese, x-Mac-Japanese SJIS-Mobile#DOCOMO SJIS-DOCOMO, shift_jis-imode, x-sjis-emoji-docomo SJIS-Mobile#KDDI SJIS-KDDI, shift_jis-kddi, x-sjis-emoji-kddi SJIS-Mobile#SOFTBANK SJIS-SOFTBANK, shift_jis-softbank, x-sjis-emoji-softbank エイリアスにShift_JISが登録されている文字エンコーディングはなかったんですが、実際にファイル出力してみたところSJISと同じっぽいです。
UTF-8環境で実行しているためか、CP932とSJIS-winで文字化けする文字に違いはありませんでした。$file = fopen('test.txt', 'w'); fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SJIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SHIFT-JIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'Shift_JIS')); #=> ??ー--??? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'CP932')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'MS932')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'SJIS-win')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'Windows-31J')); #=> 髙閒ー--㌢㏍? fwrite($file, mb_convert_encoding("髙閒ー−-㌢㏍㍿\n", 'MS_Kanji')); #=> 髙閒ー--㌢㏍? fclose($file);まとめ
UTF-8からの変換であれば、SJIS or CP932の2択で良さそうです。
Shift_JISのエイリアスであるはずのMS_Kanjiが、PHPではCP932のエイリアスとして登録されているのは不思議な感じがしました。結局SJIS-winが何を指しているのかはよくわかりませんでした。
そのうち「依存する文字集合」を確認して追記しようと思います。
- 投稿日:2021-01-07T01:03:30+09:00
PHPの??ってなに?
まだ現場経験が浅いときに思ったこと
「??ってなに?」
現場経験3か月頃、初めて下記の処理を見たとき、一体どういう処理なのか?と
悩んだ覚えがあるので、同じような方向けに記事にしました。$hoge = $a ?? null下記のような三項演算子なら知っていましたが、「??」はあまり馴染みない方も多いはず。。
$a = 1; $b = 2; $max = $a > $b ? $a : $b; echo $max;実行結果 2結論
$hoge = $a ?? nullこれは下記の処理と同じことをしています。
aに値があればaの値を代入し、無ければnullが入るようなイメージです。if ($a) { $hoge = $a; } else { $hoge = null; }以上、短い記事でしたがどなたかの参考になれば幸いです。
- 投稿日:2021-01-07T00:05:20+09:00
【API初心者】無料APIを使って簡単な飲食店検索アプリを作ろう
アプリ概要
ぐるなびAPIを利用した店舗検索が可能なWEBアプリケーションです。日本語に加え、英語、中国語(簡体字)、韓国語、ベトナム語の計5ヶ国語に対応しています。また、スマホで利用するユーザが多くなるだろうと想定して、レスポンシブデザインに対応しています。誰でも簡単に条件指定して店舗検索できることが、このアプリの最大の特徴であり長所だと言えます。
背景
2021年1月現在、世界全体でコロナウイルスによる大変な被害に見舞われています。このような状況が一刻も早く治り、以前よりも多くの人が日本に訪れることを夢見ています。実現するかどうかはわかりませんが、世界からやってくる人たちに、少しでも良いので、日本の飲食店の凄さを知ってもらいたいと願っています。どこで食べようかと場所を決める際に、簡単に飲食店を検索できたら良いのではないか、と思いついたのが、このアプリを作ろうと思った背景になります。
準備
ぐるなびWebサービスにて、新規アカウントを発行し、keyidを取得します。keyidは各種APIに送信するリクエストパラメータとして必須なので、忘れないように注意しましょう。
仕様
選択フォーム画面1、選択フォーム画面2、検索結果表示画面の3画面構成となっています。選択フォーム画面1および選択フォーム画面2にて、店舗の検索条件を指定し、検索結果の店舗一覧を検索結果表示画面に表示する簡単な仕様になっています。また、各画面において、上部のリンクから指定の言語リンクを押下することで、表示が対象の言語に切り替わる仕様になっています。
選択フォーム画面1
この画面においては、飲食店のカテゴリーおよび都道府県を選択します。カテゴリーの選択肢一覧は、keyid、対象言語をリクエストパラメータに指定し、ぐるなびの大業態マスタ取得APIから取得したレスポンスを加工して表示しています。都道府県の選択肢一覧は、同じくkeyid、対象言語をリクエストパラメータに指定し、都道府県マスタAPIから取得したレスポンスを加工して表示しています。「次へ」ボタンを押下すると、選択フォーム画面2に遷移するのですが、その際に大業態コード、都道府県コード、対象言語をGETで送信します。
選択フォーム画面2
この画面においては、選択フォーム画面1で選択した都道府県に紐づく、詳細な地域を選択します。地域の選択肢一覧は、keyid、GETで取得した都道府県コードおよび対象言語をリクエストパラメータに指定し、エリアSマスタ取得APIから取得したレスポンスを加工して表示しています。「戻る」ボタンを押下すると、選択フォーム画面1に戻ります。「送信」ボタンを押下すると、検索結果表示画面に遷移するのですが、その際に大業態コード、エリアSコード、都道府県コード、対象言語をGETで送信します。
検索結果表示画面
この画面においては、検索条件に応じた店舗一覧を表示します。店舗一覧は、keyid、GETで取得した大業態コード、エリアSコード、都道府県コード、対象言語をリクエストパラメータに指定し、多言語版レストラン検索APIから取得したレスポンスを加工して表示しています。
完成形