【PHP】下らねぇ質問はここに書き込みやがれ 10
■ このスレッドは過去ログ倉庫に格納されています
PHPに関する質問スレです
前スレ
【PHP】下らねぇ質問はここに書き込みやがれ 9
http://mevius.5ch.net/test/read.cgi/tech/1513760420/
次スレは>>980以降
本文の1行目に以下を追加すること
!extend:on:vvvvv:1000:512
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured >>780
君は一体なんの話をしてるのかね
>>781
多くの言語は0.99999とかになるのだがw mysqli関数使ってるんだが、PDOについて質問です。
別のDBMSに乗り換えるときに便利、みたいな記事をよく見ますが、DBMSごとにSQL文の制約が少しずつ違いますよね?
この差はPDO自体は吸収できませんよね?コードで分岐するしかないんですよね?
すると、MySQLしか使わない限りは、PDOを使うメリットって何でしょうか? >>786
DBMS依存の書き方が多いなら無理して使う必要もないんじゃね。
専用のやつの方がパフォーマンスもいいんだろうし。 >すると、MySQLしか使わない限りは、PDOを使うメリットって何でしょうか?
自分で使うもので将来的な移行もありえないならメリットは特にない
pdoのほうがよりモダンなコードで書けるぐらいか
パフォーマンスは公式にも書いてるけどどのAPI使ってもほぼ同じで誤差程度 >>787
>>788
レスありがとう。
そっか、じゃあインジェクション対策もしてあるからこのままで行きます。 ID:qcCZ1na20
はとりあえず日本語から勉強し直せ
アホー知恵袋より酷いぞ
つかプログラミング向いてないから手遅れになる前に諦めた方がいいんじゃね? アップロードしたファイル名をDBに書き込んでファイルはtmpディレクトリに保存しておくときって
ファイルの名前はハッシュ値に変えるべきかそのままのファイル名で処理するかどっちがいいの? いつ消えるかわからないtmpに保存しとくって解せぬ
ファイル名をハッシュ値に変える意味はわからないけどそこは好きにすればいいのでは 下記記述のようにグローバルな場所で $arr を出力することはできたのですが、
関数の中で出力するとエラーになってしまいます。
PHPだと親に位置する変数って参照できないのでしょうか?
$arr = [
'a' => 1,
'b' => 2
];
var_dump($arr);
function test() {
var_dump($arr);
};
test(); >>793
function test() {
global $arr; >>794
どうも。
教えていただいた記述ではエラーが出てしまい、下記にしたらいけました。
仕組みググってきます!
var_dump($GLOBALS['arr']); 質問です。
色の近さを測る方法ってあるでしょうか?
例えば、
A.#4169e1 B.#ff7f50 C.#dc143c
があった場合、Cにより近い色はAとBどちら?
といった感じで使いたいです。 色コードといえば、RGBとかHSVとかCYMKとか習うと思うけど、これらは数学的にいうと、(ベクトル空間みたいな)色空間上の位置を持った点を意味する。
色の近さは色空間での2点間の距離の長さ。というわけで、色空間と距離の定義しだい。 https://ja.wikipedia.org/wiki/色差
DeltaE00をRGBから計算する
面倒くさいのでライブラリ的なの探す 思った以上に難しそうだな…
16進数だからC-AとC-Bを行い絶対数の小さい方が似てる色くらいに思ってたぜ 色の近さの判断基準が分からんとな。
とにかくRGBをHSVなりに変換したとして、
色相(H)が近ければ濃さ(S)や明るさ(V)はどうでもいいのか?
どうでもよくないならそれぞれのパラメータの重みを決める必要があるな。 SASS のmixin に、そういう機能は無いのか? 単純に3次元ベクトルの距離差だけでよいじゃん
RGBなんだし 人の目に感じる色の近さは、RGBの数値だけでは判定できないな
色合いと彩度で比較する方が感覚に近い csvをアップロードして中身読み込んで確認画面を出して問題なければDBに登録する仕組み作ってるんですけど
ページ間のデータ渡しって2Mくらいのそれなりに大きいデータでもセッションで大丈夫ですか? セションの中身はディスクに書いてるんだろうから、2MBくらいなら保存自体の問題は無いんじゃね。
でも不要になったらセッションからさっさと削除しないと、毎回そのデータがメモリにロードされることになる。
セッションとは別に一時ファイルに書き出してそのファイル名をセッションで保持するのがスマートな気がするけど、一時ファイルの掃除の方法を別途考えないといけないのが面倒だな。 >>807
ありがとうございます!
ファイルに保持させる方法も考えてみます >>808
一時ファイルの掃除のためにこの辺を読んでおくといいと思う。
https://www.php.net/manual/ja/session.customhandler.php
destroy とか gc で一時ファイルを掃除する必要があるはず。 preg_match_allを使ってリンク先が画像のURL取得したいんだけど正規表現がわかりません。
これを↓
<a href="http://img.hoge/001.jpg" target="_blank">
こうしたい↓
http://img.hoge/001.jpg
作ってみたのがこれ↓
preg_match_all('/href="(.*?)(jpg|jpeg|png)?"/', $html, $imgurllist);
わかる方いらっしゃいました教えて下さい。 "の前に\が必要かも?
href=\"(.*?\.png|.*?\.jpeg|.*?\.jpeg)\"
なんてどうでしょう なんでもかんでも正規表現でやらんほうがいいよ
ちゃんとしたの書くの難しいし何より自分がわからないのは良くない
多少時間はかかるかもしれないが
getElementsByTagName('a')->getAttribute('href')でa hrefのリストとってきて
1個ずつpathinfo['extension']を見ていく感じ
pathinfo['extenstion']の?以降を除外してstrtolowerで拡張子小文字にした上で
in_arrayあたりで比較すればいいんでは? 正規表現なら一行で書けるのにごちゃごちゃ関数かます方が意味分からない あの呪文のような記述を受け付けない人もいるみたいだ
俺は好きなんだけどな >>814
一行で書いてみ
もちろん810がやろうとしてるザルなのはだめな ま、こんなもんだろ
口先だけで自信ないから書けない
正規表現なんて書けた気でいるやつが大半でバグの温床
本当にちゃんと書けるやつだけ使えな >>818
自分が有能と勘違いしてるプログラマにありがちだな
教えて→こんなこともわからないの?底辺!→はよ教えて→考える力が身につかないよ!自分でやれ!→はよ教えて→無言で逃走 先輩が書いたコードを見ると $_SERVER などの取得する値に対して
urldecode やら isset やらで本当にその値か正しいものかどうか、セットされてるかどうか
毎度調べてるようなのですが、正しくない場合の事例が書いてあるサイトってありますか?
また、この手のエスケープや存在確認やらがまとめてあるサイトもあれば教えていただけますでしょうか。
自分では追っかけきれず、毎度先輩に迷惑掛けてしまっている状態で申し訳ないっす… 横からワロス
>>817
なんでわざわざ二レス三行も書いて、一行で書けるものを書かないのか >>821
$_SERVERで取れるのは環境変数
環境変数って言うぐらいだから、その値が必ずある保証なんてないし、めちゃくちゃな値をセットする事もできる
例えば
$_SERVER['HTTP_USER_AGENT']
とかな。自分でめちゃくちゃな値をセットして自分で実験してみたらいい
isset()なんか使わんけどねw
あるか無いか分からない時は getenv() 使えばいい
urldecode()にいたっては検証用の関数ですらない
URLエンコードされたデータをデコードしてるだけ
なんていうかHTTPの基礎から理解できてない
とりあえずGoogle Chromeのデベロッパツールでも眺めてHTTPの流れから理解した方がいいんじゃね? >>818
ペチパーはクソ正規表現をネットに載せるな!って昔からよく馬鹿にされるからなぁ…
まずは>>813のようにHTMLをパースする別の手段を検討すべき
その上であえて正規表現を選ぶってのなら別にいいけどさ >>810
くそ適当に書くけど
$html = '<a href="http://img.hoge/001.jpg" target="_blank">';
preg_match_all('/href\s*=\s*([\'"])(.+?\.(?:jpe?g|png))\\1/i', $html, $match, PREG_SET_ORDER);
print_r($match);
・大文字小文字の考慮
・スペース文字の考慮
・シングルクォートで挟むのかダブルクォートで挟むのかの考慮
正規表現を使うならせめてこれぐらいはしようよw 自分で書いた>>825のクソコードを眺めて思ったがほんと>>818の言う通りだな
一字一句同意する
きちんと処理したいならHTMLパーサーを使ってきちんとパースしなされ >>810です。
皆様ありがとうございます。
勉強不足であると実感しました。
URL取得はうまくいきました。 >>821
毎度?普通はそういう繰り返し使われる処理はライブラリ化すると思うけど 正規表現なら1行で書けるといいながらその1行すら書けずに逃げた>>814が恥ずかしすぎる >>823
ありがとうございます。
色々値セットして試してみます。
ちなみにデベロッパーツールの何処をみたらHTTPの流れを知ることができるのでしょうか? >>830
上のタブでNetworkを選んでHeadersのところを見る
Request Headersに書かれてるのが、ウェブサーバに対するHTTPリクエストの内容
例えばそこにAccept-Encoding: gzip とあれば
ウェブサーバがそれを見てコンテンツをgzip圧縮してレスポンスとして返す
そしてウェブブラウザがそれをデコードして元に戻す
User-Agentなんかも書かれてるはず
Accept-EncodingにせよUser-Agentにせよあくまでも自称であり、
そこには嘘でもめちゃくちゃな文字列でもなんでも書けるんだよ
だから値を信用したら駄目ってこと >>830
自分でHTTPクライアントを作ってみるのが一番いい
fsockopen()やstream_socket_client()あたりでサーバに接続して
HTTPの命令を送ってレスポンスを受け取るみたいなコードを書けばHTTPの流れは一発で理解できる
「PHP stream_socket_client HTTP/1.1」とか適当にググったら、たぶんサンプルコードは見つかるはず 漏れは、5ch の投稿から、画像のリンクだけを取り出すために、
Ruby で、こういうモジュールを作っている
module MyUtility
require 'uri'
@@EXTS = %w(png jpg jpeg gif) # 画像の拡張子
# 画像の拡張子かどうか?
def check_picture_extname? ( picture_url )
return false if picture_url.empty?
begin
uri = URI.parse picture_url
rescue # 半角以外の文字
return false
end
file_name = File.basename(uri.path) # ファイル名
file_extname = File.extname(file_name) # 拡張子
return false if file_extname.empty?
# . を削除して、小文字にする
file_extname.delete!(".").downcase!
@@EXTS.include? file_extname # 含まれている?
end
module_function :check_picture_extname? # 公開
end >>831-832
超詳しくありがとうございます!
ググる用語まで教えていただき感謝です。
Headers はじめて開きました。
ここの情報を引っ張ってきてるんですね。
色々調べてみます。 VSCode の拡張機能の、REST Client を使えばよい
### で区切れば、いくつでも書ける。
カーソルを置いて、右クリックメニューから送信
GET http://localhost:8888/?page=2&pageSize=10 HTTP/1.1
###
POST http://localhost:8888/ HTTP/1.1
content-type: application/json
{
"name": "sample",
"time": "Wed, 21 Oct 2015 18:27:50 GMT"
}
### phpファイルにパスワードを記入しているのですが
安全でしょうか?
もしくはもっと安全な方法はありますか? 質問です。
テキストファイルにキーワードが書いてあり、
それを読み込んで一致する文字列があったらtrueを返します。
しかし、たまに一致箇所があるにも関わらずスルーされる場合があります。
なぜでしょうか?
判定は↓のような感じです。
strpos($str,'キーワード') !== false >>838
再現性のある最小コードをどうぞ
$strとキーワードじゃエスパーじゃないと分からん すみません。
解決しました。
原因は、テスト用のフォルダのパスのままになっていたことと
試運転時のデータが一部使われていた事により
一部検出されていないというおかしな状態になっているということでした。 die();
exit();
exit は言語構造です。 status を指定しない場合は括弧なしでコールできます。
って今知ったわー foreach ($this->_db->query($sql) as $v) {...}
query()やprepare()で準備した文はexecute()必須だと思ってましたが
↑の記述ではexecute()なしでSQL文を実行できているようでした
何故でしょうか? $sqlの内容が 直接実行可能なSQL文だったらそのままで行けるよ ->
=>
がよく混同する。
どれがどの用法かを一発で覚える方法ある?
数ヵ月以上使っていなかったり他言語やってたりすると覚えるのは困難。 >>845
どうも
$sql のSQL文は下記なのですが、直接実行できるときとできない場合の
見分け方ってありますでしょうか?
$sql = "select answer, count(id) as c from answers group by answer";
bindValue() とかをかましているときに execute() 使っているようなので
プレースホルダの置換しなければおk的な感じなのでしょうか? >>847
自己解決しました。
prepare() と execute() がセットで query() は単体でおkのようでした。 >>846
->これはアロー演算子だから
オブジェクトとかクラスとか呼び出したときにメソッドを呼び出すときに使うから
クラス名->メソッドとかで
=>これは普通の演算子以下とか以上とかで使うやつだから >>=>これは普通の演算子以下とか以上とかで使うやつだから
嘘つき >>850
間違ってたわ、=>これは配列で添字で関係持たせるときに使うやつだったわ
謝罪しておきます 最近はfnとセットでアロー関数使うときにも使うけどね >>856
その説明ではわかりません。
まず
・象は鼻は長い
・象の鼻は長い
の違いを教えてください なんでこうプログラマとかUNIX使いってめんどくさいのが多いかね 先にめんどくさいことを片付けるか、後からめんどくさいことにぶち当たるかの、違い 質問いいでしょうか?
ローカル環境XAMPPで動かしています。
外付けHDDから画像を表示させようとしたところ見つからないというエラーが出ました。
[an error occurred while processing this directive] 要求された URL は本サーバでは見つかりませんでした。 もし手入力で URL を入力した場合は、綴りを確認して再度お試し下さい。 [an error occurred while processing this directive]
リンクをコピーで確認したところURLの前に「http://localhost」が勝手に追加されていました。
これのせいで上手く表示されていないようです。
なんとかして画像を表示させる方法はないでしょうか? >>860
諸々の知識が足りて無さすぎるのでサーバーとはなんぞやxamppとはなんぞやってとこから勉強してどうぞ ウ〜ンやっぱ無理か
一時的にコピーくらいしか思いつかんな
データとして貼り付けるにして多いし重すぎる ドキュメントルート内のどこかからジャンクションやシンボリックリンク張るなり、サーバー設定でaliasすればいいんでね? >>863
フルパスで指定している?
ドライブ名が入っている? >>865
フルパスでやってる
ドライブ跨ぐと駄目なんだろうな 相乗りで質問させてください。
>>867 のリンク先に書いてあるような設定を済ませて、chromeでは〇〇〇.localhostといった
URLで開けるようになったのですが、それ以外のブラウザではエラーが出てしまい開けません。
改善方法はありますでしょうか?
PHPと関係ないかもしれませんが、該当スレも見当たらず…
どうかご回答よろしくお願いいたします。 virtualhostでもいいけどめんどいしalias追加でいいんじゃねえの Windows 10, WSL, Ubuntu 18.04 で、Ruby なら、Linux 側で、
1-liner で、Rubyで作られた遅いウェブサーバー、WEBrick が起動する
ruby -run -e httpd . -p 8080
そのフォルダに、index.html があれば、
Windows側から、これでブラウザでアクセスできる
http://localhost:8080
Linux側も、C ドライブ内にあるからかな?
アクセスするサーバーが、どのドライブのどのフォルダ内を、
カレントディレクトリとして起動したか 2ch風の掲示板を作ってます。
datファイルで一行に名前・メール・メッセージと管理用のIDやらを
記述するやり方で、レスアンカーやurlをループ処理の中で出力時に
aタグで囲む方法が思い付きません。
正規表現でメッセージから有無の判定はできましたが、そこから先で詰まってます。
ヒントをください。 >>872
その正規表現を貼ってごらんよ。
それ使えばできるはず。 後方参照がわからんのだろうな
matchじゃなくてreplaceでおk
正規表現でマッチした()の中身を置き換えのとこで$n or \\nで参照できる
例えばこんなん
https://ideone.com/lJv04e >>874
ありがとうございます。
早速試してみます。
何かできそうな気がしてきました! >>874
下記記述で行けました。
本当にありがとうございました(涙)
preg_replace('/>>([0-9]{1,3})/', '<a href="#$1">>>$1</a>', $message);
ちなみにセキュリティに対して理解が浅すぎるのですが、渡ってくる文字列に対して警戒していればおkで
置換でa要素を使ったり、HTMLエンティティ対象の文字列をそのまま書いても大丈夫なのでしょうか? 5chはテキストログで1レス1行が都合が良さそうなのと区切り文字が必要になるので
そのへんの改行(<br>)と区切り(<>)考慮するとエスケープ済みのほうが扱いやすい
ただ欠点としてはログサイズが肥大する
もちろん必要最小限のエスケープでもできるけどめんどくさいので完全再現じゃないが
ログ保存時
$message = preg_replace('/\r?\n/', '<br>', htmlspecialchars($_POST['message'], ENT_QUOTES, 'UTF-8'));
出力時
$message = preg_replace(['/>>([0-9]{1,3})/', '%(https?://[^\s&]+)%'], ['<a href="#$1">>>$1</a>', '<a href="$1">$1</a>'], $message);
とかなんじゃないかなと
リンクつける仕様上一旦エスケープしたのを戻す箇所があるので
そこでXSSを成立させないよう注意してコーディングする必要がある
エスケープ済みの文字は<や"のように&がつくので
[^\s&]のとこのように&でぶったぎるのが簡単
ちなみにurlの複数パラメータでも使われる&の扱いは面倒なので適当だけど
>>835のように&でリンク切れてるの見る限り5chも適当なのでおkってことで >>877
詳しくありがとうございます。
5chのログの内容は最初にチェックしてたはずなのに、すっかり忘れてました。
再度確認したところ、エスケープ処理済みな上にタグまで付いてました…
てっきり出力前にエスケープするのがPHPのルールだと思ってたのですが、
まさか事前にエスケープしておくとは…
出力時のpreg_replaceも配列にすれば一回で済むのですね…
レスアンカーとリンクで分けてました
>>835のリンクについては、専ブラで見てたので気づきませんでした。
直リン避けも考慮してhttps://まで見て、後は半角英数なら置換対象に
してしまおう!…って感じで雑に考えてました。
preg_replace('/(h?ttps?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+)/', '<a href="$1">$1</a>', $replaceMessage);
凄く参考になりました。
どうもです。 文字列と多次元配列の値に対して一括で処理できるメソッドで質問です。
下記メソッドで$hogeに多次元配列が渡ってきたと仮定しまして、
値が配列であれば再起処理でメソッドが再度呼び出されるそうです。
私の考えでは、再起処理で多次元配列の中の値が配列ではなかったときは、
Aの文字列の方に流れるのではと思っていたのですが、実際は@に流れるようです。
多次元配列の中の文字列にis_array()を掛けてもfalseなのですが、どういった理由で
@に流れるのでしょうか?
function test($hoge) {
// 配列の場合
if (is_array($hoge)) {
foreach ($hoge as $key => $value) {
// 再起処理
if (is_array($value)) {
test($value);
}
// @配列の中の値が配列でない場合
else {
...
}
}
return;
}
// A文字列の場合
return;
} @は再帰呼び出しで、Aは再帰の終了条件だね。
配列の中に配列があったときは@が呼ばれるようになってる。
再帰を一度じっくり勉強したほうがいいよ。誤字も含めて。 >>880
誤字失礼しました。
どうにも理解できなくて、再度質問しようと文字に起こしていたところ自己解決できました。
Aは文字列専用の終了条件で@は配列専用の終了条件だったようです。
再帰処理の際に値が文字列なのに、何で配列判定で true が出るのだろう?
というところが疑問だったのですが、
本来であれば配列の中の配列である [] で再帰処理されるところを、その中の値Bで
再帰処理されていると勘違いしておりました。
ご迷惑おかけしました。
$hoge = [
'piyo1',
'piyo2',
[
// B
'piyo3'
]
]; 書き方としては終了条件を早期returnして終了するべき(そうじゃないとひどく読みにくい)
一般化するなら
function apply_recursively($target, callable $callback) {
if (!is_array($target)) {
return $callback($target);
}
return array_map(function ($target) use ($callback) { return apply_recursively($target, $callback); }, $target);
// return array_map(fn($target) => apply_recursively($target, $callback), $target); // -> for PHP >= 7.4.0
} >>879
foreach 直後の if は不要で無条件に test($value) を行い、
Aは else にして @ に書いてた処理を書き、
関数の引数は function hoge(&$value) で参照で受けとるようにし、
foreach も foreach($hoge as &$value) にする。
こうしないと動かなくない? >>883
ごめんまちがい
function のくだりは function test(&$hoge) ね。 ■ このスレッドは過去ログ倉庫に格納されています