1. 相対パスを使用しないでください。
よくあるのは、
require_once('../../lib/some_class.php');
このメソッドには多くの欠点があります。
最初に指定された php インクルード パスを検索し、次に現在のディレクトリを検索します。
非常に多くのパスがチェックされます。
スクリプトが別のディレクトリにあるスクリプトによってインクルードされている場合、そのベース ディレクトリは次のようになります。
もう 1 つの問題は、スケジュールされたタスクがスクリプトを実行するとき、その親ディレクトリが作業ディレクトリではない可能性があることです。
そのため、絶対パスを使用するのが最良の選択です。
define(' ROOT' , '/var/www/project/');
require_once(ROOT . '../../lib/some_class.php');
//コードの残りの部分
絶対パスと値はハードコーディングされているので、パス /var/www/project も変更する必要があります。いいえ、__FILE__ 定数を使用できます。 :
// スクリプトが /var/www/project/index.php であるとします。
// __FILE__ には常にそのフルパスが含まれます。
define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME)) ;
require_once(ROOT . '../../lib/some_class.php');
//コードの残りの部分
これで、どのディレクトリに移動しても、
2. require、include、include_once、required_once を直接使用しないでください。
スクリプトの先頭に複数のファイルを導入できます。
require_once('lib/Database.php');
require_once('helpers/) などのクラス ライブラリ、ツール ファイル、ヘルパー関数など。 utility_functions.php');
この使用法は、より柔軟である必要があります。たとえば、
functionload_class($class_name)
。 >//クラスファイルへのパス
$ path = ROOT . $class_name . '.php');
require_once( $path ); Database');
load_class('Mail' );
このコードはさらに読みやすくなりました。
この関数は、次のように拡張できます。 ($class_name)
{
// クラス ファイルへのパス
$path = '/lib/' . $class_name . '.php'); ))
{
require_once( $path );
}
}
さらに次のことができます:
同じファイルの複数のディレクトリを検索
ディレクトリは簡単に変更できますクラス ファイルが配置される場所。コード内で分割する必要はありません。ファイルを 1 つずつ変更します。
同様の関数を使用して、HTML コンテンツなどのファイルを読み込むことができます。
3. アプリケーションのコードをデバッグし続けます。
開発環境では、データベースクエリステートメントを出力して転送します。問題のある変数値があり、問題が解決されたら、コメントするか削除します。ただし、より良いアプローチは、デバッグコードを保持することです。
開発環境では、次のことができます:
define('ENVIRONMENT' , 'development ');
if(! $db->query( $query ) {
if( ENVIRONMENT == '開発') {
echo "$query failed";
}
else
{
echo "データベース エラー。管理者に連絡してください";
}
サーバーでは、次のことができます:
define('ENVIRONMENT' , 'production');
if(! $db->query( $query )
{
if(ENVIRONMENT == '開発')
{
echo "$query failed ";
}
else
{
echo "データベース エラー。管理者に問い合わせてください。"; 🎜>}
}
4. クロスプラットフォーム関数実行の使用 コマンド
system、exec、passthru、shell_exec これら 4 つの関数は、システム コマンドの実行に使用できます。問題は、共有ホスティングの場合、一部の機能が選択的に無効になる可能性があることです。ほとんどの初心者は、使用する前に、どの機能が利用可能であるかを最初に確認する傾向があります。
より良い解決策は、その機能をクロスにカプセル化することです。 -プラットフォーム関数。
/**
ターミナルでコマンドを実行する方法
使用方法:
1.システム2.パススルー
3.実行4.シェル実行
*/
関数ターミナル($command)
{
//システム
if(function_exists('system'))
{
ob_start();
システム($command , $ return_var);
ob_end_clean();
//パススルー
; if(function_exists('passthru'))
{
ob_start();
$output = ob_get_contents();
}
//exec
else if(function_exists ('exec'))
{
exec($command , $output , $return_var)
$output = implode(" n" , $output);
}
//shell_exec
else if(function_exists('shell_exec'))
{
$output =shell_exec($command) ;
}
else
{
$output = 'このシステムではコマンドを実行できません';
$return_var = 1;
}
return array('output' => $output , 'status' => $return_var);
}
terminal('ls');
上記の関数は、一貫性を維持するシステム関数が存在する限り実行します。
5. 関数を柔軟に記述します。
function add_to_cart($item_id , $qty)
{
$_SESSION['cart']['item_id'] = $数量;
}
add_to_cart( 'IPHONE3' , 2 );
使用上面的函数添加单个项目. 而当添加项列表的时候,你要创建另一个函数吗? 不用, 只要稍加留意不同类型的参数, 就会更灵活. 如:
function add_to_cart($item_id , $qty)
{
if(!is_array($item_id))
{
$_SESSION['cart']['item_id'] = $qty;
}
else
{
foreach($item_id as $i_id => $qty)
{
$_SESSION['cart']['i_id'] = $qty;
}
}
}
add_to_cart( 'IPHONE3' , 2 );
add_to_cart( array('IPHONE3' => 2 , 'IPAD' => 5) );
现在, 同个函数可以处理不同类型的输入参数了. 可以参照上面的例子重构你的多处代码, 使其更智能.
6. 有意忽略php关闭标签
我很想知道为什么这么多关于php建议的博客文章都没提到这点.
echo "Hello";
//Now dont close this tag
这將节约你很多时间. 我们举个例子:
一个 super_class.php 文件
class super_class
{
function super_function()
{
//super code
}
}
?>
//super extra character after the closing tag
index.php
require_once('super_class.php');
//echo an image or pdf , or set the cookies or session data
这样, 你將会得到一个 Headers already send error. 为什么? 因为 “super extra character” 已经被输出了. 现在你得开始调试啦. 这会花费大量时间寻找 super extra 的位置.
因此, 养成省略关闭符的习惯:
class super_class
{
function super_function()
{
//super code
}
}
//No closing tag
这会更好.
7. 在某地方收集所有输入, 一次输出给浏览器
这称为输出缓冲, 假如说你已在不同的函数输出内容:
function print_header()
{
echo "
";
}
function print_footer()
{
echo "";
}
print_header();
for($i = 0 ; $i < 100; $i++)
{
echo "I is : $i
';
}
print_footer();
替代方案, 在某地方集中收集输出. 你可以存储在函数的局部变量中, 也可以使用ob_start和ob_end_clean. 如下:
function print_header()
{
$o = "";
return $o;
}
function print_footer()
{
$o = "";
return $o;
}
echo print_header();
for($i = 0 ; $i {
echo " I は : $i
';
}
echo print_footer();
出力バッファリングが必要な理由:
>> に送信する前に出力を変更できます。ブラウザに str_replaces 関数や preg_replaces などの監視/デバッグ HTML コンテンツを追加するなど、ブラウザへの出力と PHP 処理を同時に実行するのは非常に悪いです。途中でエラーメッセージが表示されます。これは処理と出力が混在しているためです。
xml を出力します。
$xml = '';
$xml = " < code>0
";
//xml データを送信
echo $xml;
うまく機能します。ただし、いくつかの改善が必要です。
$xml = '';
$xml = "
0< ;/code>
";
//xml データを送信
header("content-type: text/xml");
echo $xml;
注意この行は、送信されたコンテンツが XML タイプであることをブラウザーに通知します。そのため、多くの JavaScript ライブラリーには、JavaScript、CSS、jpg 画像、png 画像も含まれます。 :
JavaScript
header("content-type: application/x-javascript");
echo "var a = 10";
CSS
header("content-type: text/ css");
echo "#div id {background:#000; }";
9. mysql 接続に正しい文字エンコーディングを設定する
unicode/utf に遭遇したことがあるmysql table 8 エンコーディングで設定すると、phpadmin でも正しく表示できますが、コンテンツを取得してページに出力すると、文字化けが発生します。ここで問題となるのは、mysql 接続の文字エンコーディングです。 /データベースへの接続を試行します
$ c = mysqli_connect($this->host , $this->username, $this->password);
//接続の有効性を確認します
if (! $c) {
die ("データベース ホストに接続できませんでした:
".mysqli_connect_error());
}
//接続の文字セットを設定します
if(!mysqli_set_charset ( $c , 'UTF8' ))
{
die('mysqli_set_charset() failed');
}
データベースに接続したら、アプリケーションが複数の言語をサポートしたい場合は、これを行う必要があります。
10. htmlentities を使用して、正しいエンコード オプションを設定します。
php5.4 より前のデフォルトのエンコードです。
$value = htmlentities($this->value , ENT_QUOTES , CHARSET);
php5.4 以降は、デフォルトのエンコーディングは UTF-8 なので、多くの問題は解決されます。ただし、アプリケーションが多言語である場合は、引き続きエンコーディングの問題に注意する必要があります。
11. ob_gzhandler の使用を検討しましたか? php は、アプリケーションを作成するためにのみ使用する必要があります。サーバーとブラウザー間のデータ送信の最適化の問題については心配する必要はありません。 .
Apache の mod_gzip/mod_deflate モジュールを使用してコンテンツを圧縮します。
12. json_encode を使用して動的 JavaScript コンテンツを出力します。
PHP は、動的 JavaScript コンテンツの出力によく使用されます。 = array(
'myself.png' , 'friends.png' , 'colleagues.png'
);
$js_code = ''; >{
$js_code .= "'$image' ,"; $js_code = ' . $js_code '; 🎜>//出力は var image = ['myself.png' ,'friends.png' ,'colleagues.png' ,];
よりスマートなアプローチ、json_encode を使用します:
$images = array(
'myself.png' , 'friends.png' , 'colleagues.png'
);
$js_code = 'var images = ' . json_encode($images); >//出力は次のとおりです: var image = ["myself.png","friends.png","colleagues.png"]
エレガントに ?
13. ファイルを書き込む前に、ディレクトリの書き込みを確認します。権限
ファイルを書き込みまたは保存する前に、ディレクトリが書き込み可能であることを確認してください。これにより、Linux システムでは、権限を処理する時間が大幅に節約されます。ディレクトリのアクセス許可が不適切だと、ファイルが読み取れないなど、多くの問題が発生します。
アプリケーションが重要な情報を出力できるように十分に機能していることを確認してください。
$file_path = "/var/www/project/content.txt";
file_put_contents($file_path , $contents);
これは一般的には正しいですが、いくつかの理由で file_put_contents が失敗する可能性があります。 >>親ディレクトリが存在しません
>>ディレクトリは存在しますが、書き込み可能ではありません
>>ファイルは書き込みロックされています。
したがって、明示的に実行する方がよいでしょう。ファイルを書き込む前にチェックしてください。
$dir = '/var/www/project';
$file_path = "/content.txt"; 🎜>if(is_writable($dir))
{
file_put_contents($file_path , $contents);
} else
{
die(" ディレクトリ $dir は書き込み可能ではありません、または存在しません。チェックしてください。");
}
これを実行すると、ファイルが書き込まれた場所と失敗した理由に関する明確なメッセージが表示されます。
14. アプリケーションによって作成されたファイルのアクセス許可を変更します。
Linux 環境では、パーミッションの問題 これにより、多くの時間が無駄になる可能性があります。今後、ファイルを作成するときは必ず chmod を使用して正しいパーミッションを設定してください。そうしないと、ファイルは最初に「php」ユーザーによって作成された可能性があります。別のユーザーとしてログインして作業すると、システムはアクセスを拒否するかファイルを開くため、root 権限を取得したり、ファイル権限を変更したりするために奮闘する必要があります。
// 所有者に対しては読み取りと書き込み、他の全員に対しては読み取り
chmod("/somedir/somefile", 0644);
// 所有者向けのすべて、他のユーザー向けの読み取りと実行
chmod("/somedir/somefile", 0755);フォームの送信動作を確認するために送信ボタンの値に依存しないでください
if($_POST['submit'] == 'Save')
{ //内容を保存します
}
上記のほとんどは正しいですが、アプリケーションは多言語である可能性があります。そのため、送信ボタンの値に依存しないでください。 REQUEST_METHOD'] == 'POST' and isset( $_POST['submit']) )
{
//内容を保存します
}
これで、送信ボタンの値
16. 関数内 常に同じ値を持つ変数を静的変数として定義
//一定時間遅延する
function late()
{ $sync_lay = get_option('sync_delay');
echo "
$sync_delay 秒間遅れています...";
sleep($sync_lay)
echo "完了
";
}
静的変数を使用する 置換:
//しばらく遅延する
function late()
{
static $sync_lay = null;
if($sync_lay == null)
{
$ sync_delay = get_option('sync_delay');
}
echo "
$sync_lay 秒間遅延しています..."; ($sync_lay);
echo "Done < ;br />";
}
17. $_SESSION 変数を直接使用しないでください。
いくつかの簡単な例: 🎜>$_SESSION['username'] = $username;
$username = $_SESSION['username'];
これにより、複数のアプリケーションが同じドメイン名で実行されている場合、いくつかの問題が発生する可能性があります。 2 つの異なるアプリケーションが同じセッション キーを使用する場合があります。たとえば、フロントエンド ポータルとバックエンド管理システムは同じドメイン名を使用します。
今後は、アプリケーション関連のキーとラッパー関数:
define('APP_ID' , 'abc_corp_ecommerce'); //セッション変数を取得する関数
function session_get($key)
{
$k = APP_ID ' .' . $key;
if(isset($_SESSION[$ k]))
return $_SESSION[$k];
return false;
//関数はセッション変数を設定します
function session_set($ key , $value)
{
$k = '.' $key; = $value;
return true;
}
18. ユーティリティ関数をクラスにカプセル化する
ファイル内に多数のユーティリティ関数を定義する場合:
functionutility_a()
{
//この関数は文字列処理などのユーティリティなことを行います
}
functionutility_b()
{
//この関数はデータベース処理などの他のユーティリティなことは行いません
} functionutility_c()
{
//この関数は ...
}
これらの関数の使用はアプリケーション全体に分散されており、それらを 1 つのファイルにカプセル化することもできます。クラス:
クラス ユーティリティ
{
パブリック静的関数utility_a()
{
}
パブリック静的関数utility_b()
{
}
パブリック静的functionutility_c()
{
}
}
// これらを
$a = Utility::utility_a();
$b = Utility::utility_b() として呼び出します。 ;
明らかな利点は、php に同じ名前の Have 関数が組み込まれている場合、競合を回避できることです。
別の見方をすると、同じクラスの複数のバージョンを維持できるということです。これがカプセル化の基本的な利点です。
19. print の代わりに echo を使用します。 > 絶対に必要な場合を除いて、preg_replace の代わりに str_replace を使用します。
>> 単純な文字列には二重引用符の代わりに単一引用符を使用します。ヘッド リダイレクトの後に必ず exit を使用してください
>>> ループ内で関数を呼び出さないでください
>>>isset は strlen
>>>一貫した書式設定コード
>>>ループや if-else 括弧は削除しないでください。
次のようなコードは作成しないでください。
if( $a == true) $a_count ;
これは絶対に無駄です。
>if($a == true)
{
$a_count ; }
いいえ 代わりに、ロジックを短くしてください。 ;構文の強調表示を備えたテキスト エディタを使用すると、エラーを減らすことができます。
20 たとえば、配列内のすべての要素をトリミングしたいとします。初心者は次のことを行うとよいでしょう:
foreach($arr as $c => $v)
{
$arr[$c] = trim($v);
しかし、array_map を使用する方が簡単です:
$arr = array_map('trim' , $arr);
これは、$arr 配列の各要素に対して Trim を呼び出します。別の同様の関数は array_walk です。
21. php フィルターを使用してデータを検証する
電子メール、IP アドレスなどを検証するために正規表現を使用する必要があります。はい、今すぐ使用します。
php のフィルター拡張機能は、入力を検証してチェックする簡単な方法を提供します。
$ amount = intval( $_GET['amount'] ); $rate = (int) $_GET['rate'];
これは、必要に応じて xdebug などのプロファイラーを使用することをお勧めします。
PHP を使用して大規模なアプリケーションを開発する場合、PHP は多くの計算を実行するため、速度が非常に重要な指標になります。
xdebug とを使用してコードを最適化できます。 webgrid.
24. 大きな配列は慎重に扱う必要があります。
大きな配列と文字列は慎重に扱う必要があります。よくあるエラーは、配列のコピーによってメモリ オーバーフローが発生し、メモリ サイズの致命的なエラーがスローされることです。情報:
$db_records_in_array_format; //これは、それぞれ 20 列を持つテーブルからの 1000 行を保持する大きな配列であり、各行は少なくとも 100 バイトなので、合計 1000 * 20 * 100 = 2MB
$cc = $db_records_in_array_format ; //2MB more
some_function($cc); //Another 2MB ? これは、CSV ファイルをインポートまたはエクスポートするときによく行われます。
上記のコードによってスクリプトが実行されることはよくありません。メモリの制限によりクラッシュする可能性があります。小さい変数の場合は問題ありませんが、大きな配列を扱う場合は必ず回避する必要があります。
$a = get_large_array(); 🎜>pass_to_function(&$a );
これを行った後、(配列をコピーする代わりに) 関数に変数参照を渡します。
class A
{
関数を最初に参照してください。 )
{
$this->a = get_large_array();
$this->pass_to_function();
関数 pass_to_function()
{
/ /process $this->a
}
}
メモリを解放し、スクリプトの負担を軽減するために、できるだけ早く設定を解除します。
25. 単一のデータベース接続を使用します。最初から最後まで
スクリプトが最初から最後まで接続されていることを確認してください。常に単一のデータベース接続を最初に開き、最後まで使用してから閉じます。最後に、次のような関数で接続を開かないでください。
function add_to_cart()
{
$db = new Database();カート .....");
}
function empty_cart() {
$db = new Database();
$db->query("カートから削除します。 ....");
}
複数の接続の使用は良くありません。接続の作成には時間がかかり、メモリを消費するため、アプリケーションの速度が低下します。
データベースなどの特定の状況ではシングルトン モードを使用してください。
26. SQL を直接記述するのは避けてください。抽象化
は次のように書きすぎます。 ステートメント:
$query = "INSERT INTO users(name, email, address, Phone) VALUES('$name', '$email', '$address', '$phone')";
$ db->query($query); //mysqli_query() を呼び出します
これは堅牢な解決策ではありません。次のような欠点があります。
>>毎回値を手動でエスケープする
>クエリが正しいことを確認する
>>クエリにエラーが発生します。識別するのに長い時間がかかります (毎回 if-else で確認しない限り)
>>複雑なクエリを維持するのは困難ですそのため、関数のカプセル化を使用します:
function insert_record($table_name , $data)
{
foreach($data as $key => $value)
{
//mysqli_real_escape_string
$ data[$key] = $db->mres($value) ;
}
$fields = implode(',' , array_keys($data));
$values = "'" . implode("','" , array_values($data)) . "'";
//最終クエリ
$query = "INSERT INTO {$table}($fields) VALUES($values)"; ;
}
$data = array('name' => $name , 'email' => $email , 'address' => $address , 'phone' => $phone); 'users' , $data);
これは、より読みやすく、拡張可能です。
最大の利点は、データが配列として前処理されることです。
この関数はデータベース クラスで定義する必要があり、$db->insert_record のように呼び出すことができます。
データベースの処理を簡単にする方法については、この記事を参照してください。 >同様に update、select、delete メソッドも記述できます。試してみてください。
27. データベースから生成されたコンテンツを静的ファイルにキャッシュします。
すべてのコンテンツをデータベースから取得する場合は、生成されると、一時ファイルに保存されます。
利点: >ページの処理時間が短縮され、実行時間が短縮されます
>>データベース クエリが減ると、mysql 接続のオーバーヘッドが減ります
28. データベースへのセッションの保存
ファイルベース セッション戦略には多くの制限があります。ファイルベースのセッションを使用すると、セッションが単一のサーバーに保存されるため、クラスターに拡張できません。ただし、データベースには複数のサーバーからアクセスできるため、
セッション データをデータベースに保存することができます。 >> 同じユーザー名で同時に 2 か所にログインできない問題を解決します。
>> 🎜>
29. グローバル変数の使用を避ける
>>定義/定数を使用する
>>値を取得するには関数を使用する
>>クラスを使用し、$ を通じてアクセスするthis30. head 内での Base タグの使用
以下を参照してください: