◆ ini_set で実行時に変更はできない
◆ php.ini で On にしても効かない
◆ php-fpm が使われてると .htaccess で変更できない
◆ php-fpm の設定ファイルの方に "php_value[short_open_tag] = On" でできた

short tag

PHP 自体をテンプレートエンジンにすると

<?php func(); ?>
<?php if($message): ?>
<p><?php echo $message; ?></p>
<?php endif ?>

みたいな書き方ができます
「<?php」 って書くのが面倒ですよね

echo するなら 「<?=」 という書き方があります

<?php func(); ?>
<?php if($message): ?>
<p><?= $message ?></p>
<?php endif ?>

echo 用なので 代入や関数実行に使うと その結果を出力したくなくても出力されてしまいます
また if など制御構文を使おうとすると構文エラーになります

short_open_tag という機能を有効にすれば <? だけで済むので

<? func(); ?>
<? if($message): ?>
<p><?= $message ?></p>
<? endif ?>

これだけになってシンプルです

有効にできない

ini_set

最初は PHP の設定なので ということで

ini_set("short_open_tag", 1);

を PHP のスクリプトの最初で実行したのですが 効果なしですぐに ini_get で取得しても 0 でした

調べてみると PHP のオプションって全部 ini_set で設定できるわけじゃなくて オプションごとに設定できる場所が限られているようです
http://php.net/manual/ja/configuration.changes.modes.php
http://php.net/manual/ja/ini.core.php

short_open_tag は PHP_INI_PERDIR というもので php.ini や .htaccess や httpd.conf で設定できますが ini_set でランタイムでの変更はできないみたいです
ini_set を実行するために php コードを実行している以上 最初の php タグは設定ファイルで指定されたものになって それ以降が ini_set によって変わるとなるとパースが大変とかあるのでしょう

php.ini

上のページで設定についての詳細を見ると デフォルトは On と書いているのですよね
それなら何もしなくて使えても良さそうなのですけど
なのに ini_get で見ると 0 になっています

php.ini を見てみると

; Default Value: On
; Development Value: Off
; Production Value: Off
; http://php.net/short-open-tag
short_open_tag = Off

こういう部分がありました
Default Value は On なのに Development Value も Production Value も Off で実際に適用されている値は Off です

デフォルト値くらい守ってほしいんですけどー

とりあえず

short_open_tag = On

に変更して完了……と思ったのですが これでも動きません

反映されない

他にも設定してる場所があるのかと思いましたが

grep open_tag /etc/* -r

これで引っかかった部分で有効な行は変更したところだけです

気になったのは 「php -a」 で直接 php の REPL を使って ini_get で確認すると

php > echo ini_get("short_open_tag");
1

1 なんですよね
なのに ブラウザ画面に ini_get の結果を出すと 0 と出ます

そうなると httpd の再起動漏れが考えられるのですが もう何度も再起動しています
もしかして httpd 以外で動いてる?なんてことも考えたのですが nginx など他のサーバらしいものは入ってませんでしたし これまで httpd の再起動で変更を反映していたので httpd のはずです

.htaccess

.htaccess なら動くかな と思って今度は .htaccess に

php_value short_open_tag 1

を書いてみると エラーになります

php_flag でこう書く方法もあるようなのでやってみました

php_flag short_open_tag on

が こっちもダメでした

効かないじゃなくて .htaccess の設定にエラーがあるようなエラー画面になります
それが気になったので調べてみると php-fpm を使ってると .htaccess での設定の変更はサポートされてないという情報がありました

fpm なんて使った覚えはないのですが phpinfo() で環境情報を見てみると FPM/FastCGI のようです
apche のモジュールだと思ってたのですが 最近の fedora はデフォルトが fpm みたいですね

php-fpm

FPM だと .htaccess はダメで php.ini は無視されるし ini_set もできない これどうやっても無理なんじゃ……
そう思いながらも探し続けてると php-fpm の方の設定ファイルの /etc/php-fpm.d/www.conf の最後に

phpvalue[short_open_tag] = On

と書いて動いたという報告を見つけました

そのとおりに書いてみると ini_get で 1 となり 無事 short_open_tag が使えるようになりました

www.conf のほうは Off とも書いてなかったので関係ないだろうと思っていたのですけどこっちに書かないとダメなんですね
phpinfo の表示では php.ini が設定ファイルになっていて php.d 以下の 20-curl.ini などもロードされているのに /etc/php-fpm.conf や www.conf は設定ファイル中にはなくてロードされてないように見えます
さらに fpm.config という項目は no value とあるのですが実際にはちゃんとロードされてるようです

php-fpm のエラーがわかりづらい

これまで気づかなかったくらいなので 設定ファイルを特に変更しないなら fpm かどうかは特に困らないものでした
ただ 設定を変更するとなると php.ini はロードされてるみたいなのに設定が変わらなかったり 慣れない書き方しないといけなかったり .htaccess で php の設定できなかったりでちょっと不便が多めです

中でも 設定ファイルのエラーがあったときのエラーがわかりづらすぎました
意図せず変なテキストを貼り付けてしまったのですが それに気づかずページを開いてたら 503 のエラーになっていて ログを見ても

[proxy:error] [pid 817:tid 140082841384704] (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed
[proxy_fcgi:error] [pid 817:tid 140082841384704] [client 192.168.1.13:58970] AH01079: failed to make connection to backend: httpd-UDS

こういうのだけです
sock ファイル読めないとか言われても何が悪いのか全然わかりません
一度はわけがわからず再起動してみたのですが それでも変わらず 再起動でもダメなら設定ファイルの問題くらいしか思いつかなかったので 見直してると変な文字列が入ってるのを見つけて直せました

設定ファイルが悪いのなら何行目でエラーとか出してよ……

わかりづらいコピペミスだから目立ったものの 自然に見える形で 1 文字おかしかったとかなら 元ファイルと diff でもしないと無理だと思います
そのあたり不親切感があります

ちゃんとは覚えてないのですが apache モジュールのときは設定ファイル間違っていてもすぐに気付けていたので httpd の起動時のエラーやログで設定ファイルが間違ってるとわかるようになっていたと思います

short_open_tag は使うべき?

ところで short_open_tag はデフォルト On と書いてるのに Off にされていました
あまり推奨されてないのでしょうか

簡単に調べてみましたが悪いところは xml での問題くらいしか見当たりませんでした

XML 宣言は

<?xml version="1.0" encoding="UTF-8"?>

のように書きます

最初が 「<?」 から始まります
short_open_tag が有効なら 「<?」 で PHP コードが開始とみなされますから 「xml version~」 が PHP として解釈されてエラーになります
php として実行するファイルで XML を出力することがよくあるなら有効になっていると使いづらいと思います

ですが PHP をテンプレートエンジンとして使って XML を出力することってめったにないと思います
静的な XML ファイルなら PHP としてパースする必要がないので関係ありません
PHP でデータを埋め込む動的なものです
API が XML を返すようなケースでしょう
今は XML の API ってあまり見なくなりつつあり JSON のほうが主流です
それに XML を作る場合でも API を作るようなサービスになってくると PHP そのままじゃなくてフレームワークを使って テンプレートエンジンも Smarty とか Blade とか Twig などを使う場合が多いと思います
なので基本は short_open_tag が On で困ることはないと思います

もし XML を出力することがあっても

function xml($attr) {
return "<?xml $attr ?>"
}

という関数を用意しておいて XML 宣言はこう書けば対して文字数も変わりません

<?= xml('version="1.0" encoding="UTF-8"') ?>

それに XML 宣言だと共通部分なのでベースとなるテンプレートに一度書いておくだけで良いことが多そうなのでわざわざ関数にしなくても

<?= '<?xml version="1.0" encoding="UTF-8" ?>' ?>

にしても困らないと思います