質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

受付中

phpの関数がマニュアル通りに機能しない

nikuatsu
nikuatsu

総合スコア172

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1回答

0リアクション

0クリップ

589閲覧

投稿2022/09/17 00:22

編集2022/09/18 22:35

前提

phpで文字数のカウントに取り組んでいます。

実現したいこと

grapheme_strlenの実行に際して、マニュアル通りの結果を得たいです。

マニュアルはこちらです。

grapheme_strlen
https://www.php.net/manual/ja/function.grapheme-strlen.php

得たい結果はマニュアルの一番最後に載っているこちらです。

echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); //1 - Bingo

発生している問題

該当のソースコードが上記マニュアルと異なる結果を返し、以下7を得ます

該当のソースコード

php

echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); //7 - なぜ...?

試したこと

試したこと 1(コードの確認)

まずマニュアルのコピペミスを懸念し、改めてコピペしましたが変化なしでした。
これは「質問への追記・修正の依頼」で m.ts10806様 から改めて確認するようご指摘頂き、再三のコピペで確認致しました。

そのコピペの結果は下図です。
イメージ説明

ちなみに3v4lにマニュアルをコピペするとこうなります。
https://3v4l.org/QXCFu

以上みなさんがされても同様だと思いますので、コピペミスは考えにくい思います。

試したこと 2(バージョンの確認)

次にphpバージョンを確認すると 8.0.16 で問題はなさそうでした。

php

echo phpversion().PHP_EOL; //8.0.16

本当に 8.0.16 なのか?と疑い、「8.0ならエラーになる」という次のリンクのコードを試しました。

PHP 7.3では配列のオフセットの指定に波括弧を利用できましたが、PHP 8.0ではFatal Errorが発生します。
$hoge = [1, 2, 3];
echo $hoge{0};
https://recruit.gmo.jp/engineer/jisedai/blog/php8-version-up-notes/

しかし正しくFatal errorとなりました。

log

[17-Sep-2022 00:03:57 UTC] PHP Fatal error: Array and string offset access syntax with curly braces is no longer supported in /home/xxxxxxxxxxxx/example.com/public_html/wp-content/themes/test/header.php on line 22
試したこと 3(関数の有無を確認)

grapheme_strlenの有無を確認しましたが以下問題なくtrueでした。

php

var_dump( function_exists('grapheme_strlen') ); //true
試したこと 4(バージョンの変更)

Xサーバーの管理画面で 8.0.16 を 8.1.6 にアップデートしたものの改善は見られませんでした。
逆に 7.4.28 にダウングレードしても同様でした。

試したこと 5(JavaScriptの停止)

まさか「画面上の17に置換する」というJavaScriptでも動いているのか?と思い、ブラウザでJavaScriptを停止しましたが、さすがにそんなスクリプトはなかったようです。

試したこと 6(コマンドで実行)

Teratermから以下コードをコピペし実行しました。'abc'の方は普通に3ですが、'🏴󠁧󠁢󠁥󠁮󠁧󠁿'の方はペースト時に??????????????になってしまい14となり、どうやらコマンドでは絵文字は使えないようでした。

Teraterm

php -r "echo grapheme_strlen('abc'),PHP_EOL;" //3 php -r "echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'),PHP_EOL;" //14
試したこと 7(文字コード確認)
phpの実行で確認

次のコードを実行しましたが、UTF-8で問題ないように思われます。

php

// デフォルトの判定可能な文字コード print_r(mb_detect_order()); // 文字コード確認 $utf8s = ['テスト','🏴󠁧󠁢󠁥󠁮󠁧󠁿']; foreach( $utf8s as $utf8 ){ echo $utf8 . ':' . mb_detect_encoding($utf8).PHP_EOL; } /* Array ( [0] => ASCII [1] => JIS [2] => UTF-8 [3] => EUC-JP [4] => SJIS ) テスト:UTF-8 🏴󠁧󠁢󠁥󠁮󠁧󠁿:UTF-8 */
エディタで確認

尚、下図のようにエディタ(Notepad++)の文字コードも「UTF-8」でしたので、PHPファイル自体の文字コードも問題ないと思われます。
イメージ説明

php.iniで確認

さらにXサーバーの管理画面からphp.iniを見てみましたが、default_charset = UTF-8mbstring.internal_encoding = UTF-8で、これも問題なさそうです。

試したこと 8(他の Grapheme 関数)

Grapheme 関数が他にいくつかございましたので、以下を実行してみました。おそらく本来は同じ値になるはずですが、こちらもおかしかったです。

php

echo bin2hex('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); //f09f8fb4f3a081a7f3a081a2f3a081a5f3a081aef3a081a7f3a081bf echo bin2hex(grapheme_substr('🏴󠁧󠁢󠁥󠁮󠁧󠁿',0,1)); //f09f8fb4
試したこと 9(index.phpで実行)

WordPressを介さずpublic_html直下のindex.phpで実行しました。これもマニュアルをコピペした5行のみを記載しましたが、変化は見られませんでした。

イメージ説明

補足情報(FW/ツールのバージョンなど)

尚、ご参考になるかわかりませんが、Xサーバーを利用しWordPress上で実行しブラウザで結果を確認しています。

原因、解決策、他に試すべき事柄などについて思い当たることがございましたら、ご回答宜しくお願い致します。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

m.ts10806

2022/09/17 00:35 編集

7を返すのは2つ目のmb_strlen()です。 本当に最後の1行だけを実行していますか? grapheme_strlen()は本当に有効化されているのでしょうか?(デフォルトでは入らないはず) つまり、そもそも Uncaught Error: Call to undefined function grapheme_strlen() が発生してたりしませんか? エラー表示ONにして確認してみてください。
nikuatsu

2022/09/17 00:45

> 本当に最後の1行だけを実行していますか? はい。もう一度マニュアルをコピペし以下実行しました。(コメントアウトはマニュアルのまま。) echo strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); //28 - oh no echo mb_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); // - closer, but no echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); //1 - Bingo その結果は以下で、やはり7です。 2877 > grapheme_strlen()は本当に有効化されているのでしょうか? 次のコードを実行しました。 var_dump( function_exists('grapheme_strlen') ); 結果は次のようになりました。 bool(true) > Uncaught Error: Call to undefined function grapheme_strlen() 発生していませんでした。
m.ts10806

2022/09/17 00:54

上記記載しておいてください。
nikuatsu

2022/09/17 01:50 編集

記載しておきました。ありがとうございます。 ちなみに一番怪しいコピペミスを疑い改めてコピペしましたがダメでした。こんなことあるでしょうか。 もうXサーバーがphpを改ざんして提供している以外に考えられません…
otn

2022/09/17 10:35

'🏴󠁧󠁢󠁥󠁮󠁧󠁿'などはTeratermでは入力できないと思いますが、ファイルは具体的にどうやって作って、具体的にどうやってサーバーにコピーしていますか?
nikuatsu

2022/09/17 11:46

Teratermでは仰る通り入力できません。質問にも記載しておりますように、「試したこと 6」のコードをコピーし、Teratermにペーストするとハテナマークに変換されますので、その状態で実行しました。なので14となります。ファイルというのはなんのファイルですか?Teratermではファイルは呼んでおりません。echoの実行のみです。
m.ts10806

2022/09/17 11:58

>もうXサーバーがphpを改ざんして提供している以外に考えられません… それは明確に「ない」と言い切れます。 迷惑行為をしているなら即アカウント自体を無効にしますし、 そうでないなら1ユーザのテストプログラム程度にわざわざ手を入れることはないです。 監視必要なくらいなら実行させません。 一応以下では1が出ました。 https://3v4l.org/QXCFu ただ見ての通り、スペースが結構あります。 そこをカウントされてるとかはないでしょうか? また、そのスクリプトファイルの文字コードはUTF-8になっていますか? 確認してください。
otn

2022/09/17 13:02

> ハテナマークに変換されますので、その状態で実行しました。 ??? echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); というプログラムを次項したのでは無いのですか??? そのプログラムファイルは(Teratermから入力したのでは無いだろうから)具体的にどうやって作って、具体的にどうやってサーバーにコピーしていますか? という質問なのですが???
nikuatsu

2022/09/17 13:48

otn様 うーん、何がそちらの理解の妨げになっているかわかりません。以下は繰り返しになってしまいますが、正確な表現を心がけてみます。なんとか頑張って読解してください。 まず「試したこと 6」に記載してあるコードをTeratermにペーストすると、「試したこと 6」に記載してあるようにハテナマークの連続になります。これは「試したこと 6」に記載してあるようにTeratermから実行しました。すべて記載してある通りです。 試しに php -r "echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'),PHP_EOL;" をTeratermにペーストしてみてください。ハテナマークの連続になります。 「>Teratermから入力したのでは無い」ということはありません。「試したこと6」に記載してあるようにTeratermにペーストして実行しています。
nikuatsu

2022/09/17 14:08

m.ts10806様 さすがにないですよね… 「スペースがカウントされている」の件は意味が理解できませんでした。 文字コードの件は「試したこと 7」として追加させて頂きまして、問題ないように思われます。 アドバイスありがとうございます
otn

2022/09/17 15:38

そもそも、echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); は一度も実行しておらず、 echo grapheme_strlen('??????????????'); しか実行していないと言うことですか? 質問を読んで、そこに書いてある通り、 「echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); を実行したら 7が表示された」 ということかと思ったのですが、それは嘘? 「echo grapheme_strlen('??????????????');を実行して14が表示された」 といことなら、そりゃそうですとしか言い様がないです。
otn

2022/09/17 15:48 編集

他のコメントも含め、読み返すと、やはり echo grapheme_strlen('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); を実行したと思えるのですが、 これで3度目の質問ですが、そのプログラムが書かれたファイルはどうやって作ってどうやってサーバー上に置いたのですか?Windows上で作ったのではと推測しています。 (この文章でどこか意味のわからないところはありますか?)
otn

2022/09/17 16:21

echo bin2hex('🏴󠁧󠁢󠁥󠁮󠁧󠁿'); で、 f09f8fb4f3a081a7f3a081a2f3a081a5f3a081aef3a081a7f3a081bf が表示されますか? echo bin2hex(grapheme_substr('🏴󠁧󠁢󠁥󠁮󠁧󠁿',0,1)); ではどうですか?
m.ts10806

2022/09/17 21:02 編集

Windowsメモ帳でPHPマニュアルのコード貼り付けて見た感じだとすごーく「7」って出そうな感じですね。 https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/47737c84-5061-40c6-98c2-203916178e2a.png テキストエディタだと https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/28786235-dbfa-4679-b880-ba22e58c224b.png まぁコピペしようっても、HTMLとしては結構細かく分けられてるので、コピペ先の環境によって解析結果が変わるようには思いますが。 https://ddjkaamml8q8x.cloudfront.net/questions/2022-09-18/35ea5f4c-7f9b-4083-bd80-f48a3a092280.png >「スペースがカウントされている」の件は意味が理解できませんでした。 私が提示した3v4lを見てもらえれば分かりますが、コードエディタ部分に絵文字以降にスペースが沢山出ています。 そこも貼り付けられてしまう環境にてファイルを作って実行されたのではという懸念です。 追記された「WordPress上で」というのはotnさんの依頼には応えられていません。 このテストプログラムをどいうファイル名で作成し、どこに置き、どのように実行(アクセス)しているのかです。 WordPressの機能の中のPHPファイルに書いているのですか? てっきりPHPマニュアルの5行だけをコピペしたtest.phpのようなものを準備してブラウザもしくはphpコマンドでそのphpファイルにアクセスしたのかと思っていたのですが。 あと文字コードについてはPHPファイル自体の文字コードも関係します。 確認されたのはプログラム内の文字コード(宣言)だと思います。
nikuatsu

2022/09/17 21:02

otn様 まず bin2hex の件は「試したこと 8」に追加させて頂きました。 そして「試したこと 6」のみ実行はTeratermで、これがハテナマークに変換され14となると記載しています。7になるのは「該当のソースコード」でこれがハテナマークに変換されることはありません。そして「該当のソースコード」と「試したこと1、2、3、4、5、7、8」はXサーバーでWordPressのheader.phpに記述して実行しています。filezillaでアップロート致しました。
m.ts10806

2022/09/17 21:03

コメントに長々追記してるので、そちらも確認を。 WordPress度外視で実行しないと有効性は証明できないと思います。
nikuatsu

2022/09/17 21:44 編集

m.ts10806様 > そこも貼り付けられてしまう環境にてファイルを作って実行されたのではという懸念です。 スペースの件理解が追いつきました。多方面からのアドバイス誠にありがとうございます。 私のエディタは Notepad++ で、ペーストすると次の画像のようになり、見た感じスペースはありません。 https://imgur.com/a/icPMhQB > てっきりPHPマニュアルの5行だけをコピペしたtest.phpのようなものを準備してブラウザもしくはphpコマンドでそのphpファイルにアクセスしたのかと思っていたのですが。 すべて仰る通りです。 header.phpは5行のみです。 パスは「試したこと2」の記載と同様で次のパスです。 /home/xxxxxxxxxxxx/example.com/public_html/wp-content/themes/test/header.php (一般的にXサーバーでWordPressを使う人のほとんどは「簡単インストール」という機能を介してこのディレクトリにheader.phpが入ります。) そして「該当のソースコード」と「試したこと1、2、3、4、5、7、8」は、ブラウザでアクセスして結果を確認しています。 > あと文字コードについてはPHPファイル自体の文字コードも関係します。 > 確認されたのはプログラム内の文字コード(宣言)だと思います。 これは「PHPファイル自体の文字コード 確認」と検索しましたが方法がわからずでした。 > WordPress度外視で実行しないと有効性は証明できないと思います。 まったく仰る通りでした。「試したこと 9」に追加させて頂きましたが、public_html直下のindex.phpでも変化は見られませんでした。
m.ts10806

2022/09/17 21:28

>header.phpは5行のみです。 WordPressに取り込まれてる機能に入ってる時点で純粋なPHPからは離れると思います。 public_html配下に適当なPHPファイルを別途新規で作ってアップロードして実行してください。
nikuatsu

2022/09/17 21:42

m.ts10806様 > WordPress度外視で実行しないと有効性は証明できないと思います。 > public_html配下に適当なPHPファイルを別途新規で作ってアップロードして実行してください。 仰る通りでした。こちらは「試したこと 9」に追加させて頂きました。 > 使ってるエディタにおける文字コードの確認の仕方を調べないと意味がないです。 ありがとうございます。「試したこと 7」に加筆させて頂きました。
m.ts10806

2022/09/17 22:08

次。 ①2877が出ている画面キャプチャを提示してください。 ②先に私が提示した実行結果 https://3v4l.org/QXCFu のコードをコピペして実行してみてください。 ③ご自身で https://3v4l.org/ にてPHPマニュアルからコピペして実行した結果を教えてください。
nikuatsu

2022/09/17 23:09 編集

m.ts10806様 > ①2877が出ている画面キャプチャを提示してください。 こちら https://imgur.com/a/0T41c1u です。 > ②先に私が提示した実行結果 https://3v4l.org/QXCFu のコードをコピペして実行してみてください。 そのコードをコピーしてエディタにペーストすると、その見た目表示されているようなスペースはなくなり、2つ前の返信の https://imgur.com/a/icPMhQB と同じようにペーストされます。 そしてペーストしたものをfilezillaでアップロードしてブラウザから見てみると➀と完全に同じでした。 (以上の➀と➁は、WordPressを介さずpublic_html直下のindex.phpで実行致しました。) > ③ご自身で https://3v4l.org/ にてPHPマニュアルからコピペして実行した結果を教えてください。 ご提示の https://3v4l.org/QXCFu と完全に同じです。スペースが見た目にあり、実行すると2871となります。こちら https://3v4l.org/QXCFu です。
m.ts10806

2022/09/17 22:52 編集

質問本文に追記を 画像も他サービスではなくteratailの画像添付機能で。
otn

2022/09/18 05:55

サーバー上のファイルの中身が期待通りになっていない可能性もあると思って作成方法・転送方法などを聞いたのですが、(RloginなどちゃんとUnicodeを扱える端末でログインしてサーバー上でvi等で作成という方法もあるので) bin2hexで調べた方が確実だなと質問を切り替えました。ファイルの中の文字は大丈夫そうなので、やはり実行環境のほうですね。php.iniの範囲だと関係するのは intl.default_locale くらいしか無さそうですが、おそらくそこでは無いと思います。 この数行のファイルを直接実行していないとは思ってもいなかったのですが、直接実行しても同じということなので、これ以上はちょっとわからず、他の方にお任せします。
nikuatsu

2022/09/18 11:39

otn様 ありがとうございます。bin2hexで調べるというのはまったく発想になかったので助かりました。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。