PHP

あくまでもテスト用にPHP内であるURLからファイルをダウンロードしてそのまま出力する、その際SSLの確認を行わない
っというプログラムを作った。あくまでもテスト用に。大事なことなので二度言いましたよ。
そのやり方は書きません。怒られそうだから(^_^;

その中で、どうせならファイル内容から mime type を自動判別してContent-Type ヘッダを出力しよう。となった。
mime type 取得なら素直に mime_content_type 関数を使うところだが…
パラメータ
filename 調べるファイルへのパス。

てな具合で、ファイルパスを指定しかできない。
さあ困った。とググっていると、
しかし、2022年現在ではこのファンクションは使いにくいファンクションです。一時期は「非推奨」という扱いになり、廃止が検討されていたり、また現在でも標準では利用できずに「php.ini」という設定ファイルを編集しなければ使えない環境などもあります。

なんと!mime_content_type 関数って使えないのーっ!?(※フツーに使えるみたいです;文末参照)
そうかそれじゃ仕方ない。finfo を使いましょう。
で、見つけちゃったの。
finfo::buffer — 文字列バッファの情報を返す

おーこれこれ。引数にファイルを格納した変数を渡せる。
しっかし、この公式マニュアル、関数の説明が
この関数は、バイナリデータの情報を文字列形式で返すために使用します。
の一文だけ。ナンノコッチャわからんやん。。まあ例を見ればわかるけど。

ちゅーわけで、↓こんな感じになりましたとさ。
$cont = file_get_contents($url, false, stream_context_create(ゴニョゴニョ));
$f = new finfo();
$type = $f->buffer($cont);
if ($type) header("Content-Type: {$type}");
echo $cont;


※mime_content_type 関数の非推奨について
うーん、どうやら mime_content_type 関数は非推奨では無いようです。ってか、ハッキリと現時点では非推奨ではありません。実際に一時期非推奨になったことがあったけどやめた。非推奨になった根拠も不明。別にちゃんと使えるやん。躊躇なく使っていいよ。っということのようだ。
↓参考文献
「mime_content_typeは非推奨ではない」ということで良いでしょうか?
PHP :: Doc Bug #71367 :: claim mime_content_type is deprecated
echo date('Y/m/d', strtotime('2000/0/0')); // 1999/11/30

「ゼロ月」は1月の前の月だから、前年の12月。
「ゼロ日」は1日の前の日だから、前月の末日。
つまり「ゼロ月ゼロ日」は前年の12月の前月の末日。つまり前年の11月の末日。
よって2000年0月0日は1999年11月30日となる。

ちなみに、下記のように0年0月0日としても同じ1999年11月30日が出力される。
echo date('Y/m/d', strtotime('0/0/0')); // 1999/11/30

これは、「0年」は年の短い表現と解釈されて2000年となるため。
…と思ったけど違うかも。

echo date('Y/m/d', strtotime('1/0/0')); // 1999/12/31

echo date('Y/m/d', strtotime('2/0/0')); // 2000/01/31

あー、mm/dd/yy形式と判定されるのねー。
「1/0/0」 → 「01/00/2000」 → 2000年1月0日 → 1999年12月31日
「2/0/0」 → 「02/00/2000」 → 2000年2月0日 → 2000年1月31日
eval関数を使います。
いや多分、掲題のようなことをしたくて探している人にとっては「そんなの知っとるわい!」なんでしょうけど、違うんです、、、多分。
多分私と同じであれば、PHPタグ外の文字列も含めて出力したい。
イメージ的には、文字列を一度PHPファイルに出力して、それを実行する、という感じです。
そんな話なんです。違ったらすみません。

答えは↓です。
eval('?>' . $str);

これで、例えば$strの中身が
1 + 1 = <?php echo 1 + 1; ?>

だったとすると、出力は
1 + 1 = 2

となります。

こんなことできるんですね。全く盲点でした。
なぜできるのかを考えると、おそらく、evalに渡す文字列はPHPタグに囲まれているものと想定されているため、こんな感じで処理されるのでしょう。
'<?php' + evalに渡された文字列 + '?>'

上の例で言うと、
<?php?>1 + 1 = <?php echo 1 + 1; ?>?>

なにかに似ていると思ったら、SQLインジェクションだね。。

これ、たまたま見つけたんだけど、あまり知られてないよね?
もしかして、広めないほうがいいってやつ?

あれ、こんな夜中に誰か来
HTMLで下記のように「menu-open」クラスをつければ良い。
<li class="nav-item has-treeview menu-open">

っという話ではなく、HTML出力が終わってから、javascriptで開きたいという話です。

ドキュメント(Treeview Plugin | AdminLTE v3.2 Documentation)読んでメソッドを叩いて、出来上がり…って、あれ、メソッド無いのー?

ググっても見つからない。AdminLTEってマイナーなん?

仕方がないので、手動?で開くことにした。
<script>
jQuery($ => $('.nav > .nav-item.has-treeview:not(.menu-open) > .nav-treeview > .nav-item > .nav-link.active').each(function(){
$(this).closest('.nav-item.has-treeview').addClass('menu-open').children('.nav-treeview').show();
}));
</script>

↑これを</body>タグの上に入れれば動くはず。
詳しい説明は、今はできませんorz...

【追記】treeviewウィジェットの最小構成が分かってなかった。ていうか今でもわか蘭けど。
↓なるべく最小構成に寄せてみたので、上記ので『動かねぇよ糞がっ!』となったヒトは試してみて
<script>
jQuery($ => $('[data-widget="treeview"] > .nav-item:not(.menu-open) > .nav-treeview > .nav-item > .nav-link.active').each(function(){
$(this).closest('[data-widget="treeview"] > .nav-item').addClass('menu-open').children('.nav-treeview').show();
}));
</script>

これでも動かなかったら…ゴメンナサイm(_ _)m💦
藁をもすがる思いでやってみて動かなかった時ってイラッとしますよね(T_T)

でもね、ウチのような弱小閑散ブログに対し、過大な期待は禁物。「どーせ動かないんでしょ」くらいの気持ちでお試しいただくのが健康のためとご提言申し上げ奉り候。
すごい遠回りした。結論から書くと、「base64エンコード」がそれです。
Webアプリケーションで使用するなどでURLのクエリストリング内で使うような場合は「base64urlエンコード」を使いましょう。(base64エンコードしたものを更にurlencodeしても良いですが…)
これはPHP組み込み関数には存在しないので自分で定義。
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
(PHP: base64_encode - Manual のコメント欄より引用)
以上。

続きを読む