ホームページ >バックエンド開発 >PHPチュートリアル >[Li Jingshan php] thinkphp のコア ソース コードのコメント |php
<code><span><?php</span><span>// +------------------------------------- -------- ----------------------------------</span><span>// ThinkPHP [ WE |考えるだけでできます ]</span><span> // +-------------------------------------- ------------ -----------------------</span><span>// | 著作権 (c) 2006-2014 http:/ /thinkphp.cn 無断複写・転載を禁じます</span><span>// +------------------------------------- ------------ ---------------------</span><span>// ライセンス付き ( http://www.apache.org/ |ライセンス/LICENSE-2.0 )</span><span>// +- -------------------------------------- ------------ ------------------</span><span>// | 著者: liu21st <liu21st@gmail.com></span><span>// +---------- -------------------------------------- ----------- ----------</span><span>/*** システム関数ライブラリを考える*/</span><span>// 生徒の皆さん、前回の授業で、さまざまな事前定義済みの定義を完了しましたthinkphp の変数</span><span>// 重要なポイントは次の点に分けることができます: </span><span>// 最初: Web によってロードする必要があるプロジェクト ドキュメントの場合、thinkphp は dirname メソッドを使用して結合してロードします </span><span>/ ////// といったスラッシュが特徴です</span><span> // thinkphpのコアフレームワーク部分であるインポートが必要なファイルについては、読み込み方法が__DIR__方式を採用しているのが特徴です</span><span>// \\ </span><span>// のようなバックスラッシュ。もちろん、これらはウィンドウに基づいています。次の方向では、祖先 app_PATH と think_PATH の 2 つのパスに分割されます</span><span>// 2 番目: 記録できるのは </span><span>//フレームワークプログラムとしては、実行時間とスクリプトの消費メモリを記録できる必要があるので、迷わずmirctimeとmemory_get_usageをonにしました</span><span>// この瞬間が時間とメモリの起点となります。 </span><span>// 3 番目: 注目すべき点は次のとおりです: </span><span>// システム定数を定義するには const と define を使用しますが、const</span><span>// を使用すると、これが完全に固定化されることを意味します。ユーザーが独自のアプリを作成するときにそれを変更できるようにします。 システムはそれを定義する前に、それが定義されているかどうかをチェックします </span><span>// const を再定義する方法はありません </span><span>// 概要 これら 2 つの唯一の違いは使用法です。総集編! </span><span>// 4番目: システム定義済み変数[GPC]とテキストデータストリーム </span><span>// 基本的には非エスケープ処理と言えますが、addsalsheのようなものはありますか </span><span>// 5番目: phpの解釈と通信方法Webサーバーのcgi</span><span>// オペレーティングシステムを判断する</span><span>// コマンドラインツールがサーバーから逃げていないか判断する</span><span>// 6回目: ROOTファイルと_FILE_ファイルの定義の不一致について、やり直し マルチプラットフォーム定義により、プラットフォームの移植性が向上します。 </span><span>// つまり、定義とそのクロスプラットフォーム機能を標準化します。 </span><span>// 次に、これらのパブリック関数をfunctions.php 20151205に説明します</span><span>/*** マルチレイヤー コントローラーのインスタンス化形式: [resource://][module/]controller *<span> @param</span> string $name リソース アドレス *<span> @param</span> string $layer コントロール レイヤ名 *<span> @param</span> 整数 $level コントローラー レベル *<span> @return</span> ThinkController|false*/</span><span>// この関数は、内部呼び出しを容易にするためにマルチレイヤーコントローラーのインスタンス化関数を実行します。アプリアプリケーションの作成。</span><span><span>関数</span><span>A</span><span>(<span>$name</span>,<span>$layer</span>=<span>''</span>,<span>$level</span>=<span>0</span>)</span> {</span><span>static</span><span>$_action</span> = <span>array </span>() ;<span>// ここでは、単一列インスタンス化モードを実装するために静的ストレージ配列が定義されています </span><span>$layer</span> = <span>$layer</span>? : C(<span>'DEFAULT_C_LAYER'</span>); <span>//'DEFAULT_C_LAYER' => Controller ', // デフォルトのコントローラーレイヤー名</span><span>$level</span> = <span>$level</span>? : (<span>$layer</span> == C(<span>'DEFAULT_C_LAYER'</span>)?C(<span>'CONTROLLER_LEVEL'</span>):<span>1</span> ) ; <span>// 'CONTROLLER_LEVEL' => 1,</span><span>if</span>(<span>$_action</span>[<span>$name</span>.<span>$layer</span>]))<span>// 受信したコントローラーとその対応するレベルのデフォルト: コントローラー 1 レベル return</span><span>return</span><span>$_action</span>[<span>$name</span>.<span>$layer</span>]; <span>$class</span> = parse_res_name(<span>$name</span>,<span>$layer</span>,<span>$level</span>); <span>// </span><span>if</span>(class_exists(<span> $) で渡されたコントローラー名レベルのクラス名に基づいて、対応するクラス名を取得しますclass</span>)) { <span>// 上記に基づいて生成されたクラス名が存在する場合はインスタンス化されます</span><span>$action</span> = <span>new</span><span>$class</span>() <span>// Instantiation</span><span>$_action</span>[ <span>$ name</span>.<span>$layer</span>] = <span>$action</span>;<span>// インスタンス化されたオブジェクトを静的配列に格納します </span><span>return</span><span>$action</span>;<span>// インスタンス化ステータスを返す </span> }<span>他</span> { <span>return</span><span>false</span>; } <span>// 例: $name = 'admin' 結果は、AdminController.class.php ファイルの下の $class = AdiminController クラスになります。 </span> } <span>// 概要: 実際、これは、渡した $name に基づいて、インスタンス化されたさまざまなオブジェクトを返すことです。 $name に存在できるオプションは次のとおりです: </span><span>// A('[Project://][Group/]Module','Controller Layer name') 現時点では、このレベルは基本的に使用されないように感じます。 </span><span>// 救助を待っています</span><span>// さて、学生の皆さん、今日は続きをしましょう。昨日は A 関数について学びました。これは実際には、さまざまなパラメーターに基づいてさまざまなコントローラー クラスをインスタンス化する関数関数です </span><span>// A に注意してください。関数が追加されました 異なる入力パラメータを変換する対応するクラスの名前と場所が与えられました</span><span>// 次にB関数の機能を見てみましょう</span><span>/***アクションを実行する *</span> @param<span> string $name 動作名 *<span> @param</span> string $tag タグ名 (動作クラスを渡す必要はありません) *<span> @param</span> パラメータに渡される混合 $params *<span> @return</span> void*/<span></span></span>function<span><span> B</span><span>(</span>$名前<span>, <span>$tag</span>=<span>''</span>,&<span>$params</span>=NULL)<span> {</span></span>if</span>(<span>''</span>==<span>$tag</span>){ <span>$name</span> .= <span>'動作'</span>; } <span>return</span> ThinkHook::exec(<span>$name</span>,<span>$tag</span>,<span>$params</span>); } <span>// 文字通りに言えば、これは特定の動作を実行する関数です。 </span><span>// 対応するラベルがない場合、デフォルトの動作はフック関数を見つけて実行することです </span><span>// もう 1 つの注意点は、その $ です。 params 実際、これは通常の値によるコピーではなく、値による導入です。このようにして、受信パラメータを返さずに変更できます。 </span><span>// フック関数の特殊な状況に応じて、通常はアドオンの下に設定されます </span><span>// デフォルトは $name 動作の組み合わせです </span><span>// デフォルトの実行関数は run です</span><span>// ファイルの場所 "Addons\ {$name }\{$name}アドオン";</span><span>// $class = $name.'Behavior';</span><span>// $tag = 'run';</span><span>// return $addon->$tag( $params) ;</span><span>// 要約すると、実際、B 関数はプラグインを実行する 2 つのタイプ [内部/外部] であり、プラグインの開始位置を導入します。スタート関数を実行します。 </span><span>// return $class->run(parameter);</span><span>// この C 関数は非常によく使われる関数なので、通常は省略できます。慎重に</span><span>//</span><span>/*** 構成パラメータの取得と設定、およびバッチ定義のサポート *</span> @param<span> string|array $name 構成変数 *<span> @param</span> 混合 $value 設定値 *<span> @param</span> 混合 $default デフォルト値 *<span> @return</span> 混合*/<span></span></span>function<span><span>C</span><span>(</span>$name<span>=null, <span>$value</span>=null,<span>$default</span>=null)<span> {</span></span> // 初期化コンテナを定義します。これは 1 回だけ初期化できます </span><span>static</span><span>$_config</span> = <span>array</span>();<span>// 古典的な静的グローバル変数の登録。実際には複数のページに対して単一のプロセスを実行するときに有効です。ロードが異なると、効果は明らかではありません。ここは最適化できるところです。</span><span>// パラメータなしですべてのケースを取得 1</span><span>if</span> (<span>empty</span>(<span>$name</span>)) { <span>// これは大きなトリックです。つまり、C() を呼び出すときに、内部の When に注意してください。それは空です、あなたの家族全員が返されます。 </span><span>戻る</span><span>$_config</span>; } <span>// 設定取得または代入の実行を優先する 2</span><span>if</span> (is_string(<span>$name</span>)) { <span>// 文字列の場合は配列形式にはなりません </span><span>if</span> (! strpos(<span>$name </span>, <span>'.'</span>)) { <span>// 接続記号がなければ2.1として記録できます。ちょっと多すぎると思いますが、ストレージとの互換性のためです。配列の形式。リュー爺さん、あなたにとってそれは本当に簡単なことではありません。 </span><span>$name</span> = strtoupper(<span>$name</span>); <span>// すべて大文字であっても、これは互換性に対処する良い方法であり、学生はそこから学ぶことができます。 </span><span>if</span> (is_null(<span>$value</span>)) <span>// これは実際には分割でき、2.1.1</span><span>return</span><span>isset</span>(<span>$_config</span>[<span>$name</span>]) <span> $ として記録されます。 _config</span>[<span>$name</span>] : <span>$default</span>; <span>// ここの 3 項は非常に賢く、2.1.1.1 と 2.1.1.2 に分割できます</span><span>$_config</span>[<span>$name</span>] = ... 'zhangsan'); は Zhang San に名前を割り当てます<span></span>// $name = C('name') が名前の割り当てを読み取る場合、上記のステートメントが実行されたばかりの場合<span></span>// は $name です張三<span> } </span>// 2 次元配列の設定とサポートの取得 <span></span>$name<span> =explode(</span>'.'<span>, </span>$name<span>); これは 2 次元配列のサポートを追加するだけです。ここで問題があります。つまり、2 次元配列の子要素は大文字ではありません </span><span>$name</span>[<span>0</span>] = strtoupper(<span>$name</span>[<span>0</span>]); <span>if</span> (is_null(<span>$value</span>)) <span>return</span><span>isset</span>(<span>$_config</span>[<span>$name</span>[<span>0</span>]][<span>$name</span>[<span>1</span>]])? [<span>$name</span>[<span>1</span>]] : <span>$default</span>; <span>$_config</span>[<span>$name</span>[<span>0</span>]][<span>$name</span>[<span>1</span>]] = <span>$value</span>; <span>return</span><span>null</span>; } <span>// バッチ設定 シナリオ 3 データを直接結合します。実際、私のように IQ が低い人にとっては、あまり使用されませんが、時々使います。 </span><span>if</span> (is_array(<span>$name</span>)){ <span>$_config</span> = array_merge(<span>$_config</span>, array_change_key_case(<span>$name</span>,CASE_UPPER)); <span>return</span><span>null</span>; } <span>// その他の状況 </span><span>return</span><span>null</span> <span>// 不正なパラメータを避ける</span>; } <span>// さて、生徒の皆さん、ありがとう。次のクラスに進みます! </span><span>// 実際、前回のコースでは C 関数について説明しましたが、関数に関しては設定ファイルに制限されないようにしてください。 </span><span>// 今日は D 関数を続けます。この関数は、thinkphp Always の使用全体で使用されます。</span><span>//Modelクラスをインスタンス化する関数です</span><span>/*** モデルクラスの形式をインスタンス化する [resource://][module/]model *<span> @param</span> string $name リソース アドレス *<span> @param</span> string $layer モデル レイヤ名 *<span> @return</span> ThinkModel*/</span><span><span>function</span><span>D</span><span>(<span>$name</span>=<span>''</span>,<span>$layer</span>=<span>' '</span>)</span> {</span><span>if</span>(<span>empty</span>(<span>$name</span>)) <span>return</span><span>new</span> ThinkModel <span>//入力パラメータが空の場合は、デフォルトのモデルを直接返します</span><span>static</span><span>$_model; </span> = <span>array</span>(); <span>// それ以外の場合は、静的インスタンス化ウェアハウスを作成できます </span><span>$layer</span> = <span>$layer</span>? : C(<span>'DEFAULT_M_LAYER'</span>); <span>// ここでデフォルトのレイヤーを確認します。それは </span><span>if</span>(<span>isset</span>(<span>$_model</span>[<span>$name</span>.<span>$layer</span>])) <span>// 実際、これは の応用アイデアです。単一列 </span><span>return</span><span>$_model</span> [<span>$name</span>.<span>$layer</span>]; <span>$class</span> = parse_res_name(<span>$name</span>,<span>$layer</span>); <span>//この関数にはファイルをインポートする機能が含まれています</span><span>if</span>(<span>$ class </span>)) { <span>// 存在する場合は、直接ロードしてインスタンス化します</span><span>$model</span> = <span>new</span><span>$class</span>(basename(<span>$name</span>)); }<span>elseif</span>(<span>false</span> === strpos(<span>$name</span>,<span>'/'</span>)){ <span>// クラスファイルが見つからない場合は、クラスが見つからないことを意味します</span><span>// 自動的に次のパブリック モジュールをロードします。 Model </span><span>if</span>(!C(<span>'APP_USE_NAMESPACE'</span>)){ <span>// パブリック モデルが指定されていない場合は、パブリック モデルにアクセスしてください。 import(</span>'Common/'<span>.</span>$layer<span>.</span>'/'<span>.</span>$class<span>); </span>//デフォルトのパブリックモデルの保存場所<span> }</span>他<span>{ </span>$class<span> = </span>'\Common\'<span>.</span>$layer<span>.</span>'\'<span>.</span>$name<span>.</span>$layer<span>;</span>// 動作しない場合は、デフォルトのクラスをインスタンス化します<span> } </span>$model<span> = class_exists(</span>$class<span>) </span>new<span></span>$class<span>(</span>$name<span>) : </span>new<span> ThinkModel(</span>$name<span>); }</span>else<span> { </span>// それ以外の場合、ログエラーは基本クラスをインスタンス化し、それを返します<span> ThinkLog::record(</span>'D メソッドのインスタンス化でモデル クラスが見つかりませんでした'<span>.</span>$class<span>,ThinkLog::NOTICE); </span>$model<span> = </span>new<span> ThinkModel(basename(</span>$name<span>)); } </span>$_model<span>[</span>$name<span>.</span>$layer<span>] = </span>$model<span>//履歴に保存 </span><span>return</span><span>$model</span>;<span>//現在のインスタンス化されたクラスを 3 つの方法で返す </span> のインスタンス化 } <span>// 例外のスローは基本的にカプセル化であり、直接転送されますが、そのコア コードには何もありません。 </span><span>// PHPのデフォルト例外クラスを継承するだけです</span><span>/**&#&*/</span><span><span>Function</span><span>e </span>新しい<span> Think</span>Exception<span>(</span>$msg</span>, <span>$code<span>); } </span>// これは、ファイルによるデータの高速な保存と読み取り操作の問題です。 <span></span>/*** スロー例外処理 *<span> @param<span> string $msg 例外メッセージ *</span> @param<span> 整数 $code 例外コードのデフォルトは 0 です *</span> @throws<span> *</span> @return</span> void*/</span><span></span>function<span></span>F<span></span>(<span>$name</span>, <span>$value</span>=<span>''</span>, <span>$path<span>=DATA_PATH)</span> {<span></span>static<span></span>$ _cache<span> = </span>array</span>(); <span>// これは同じ古いトリックですが、 <span></span>$filename<span> = </span>$name<span> .ファイル ディレクトリも非常にシンプルです。直接使用するphpファイル </span><span>if</span> (<span>''</span> !== <span>$value</span>) { <span>// 値がある場合 </span><span>if</span> (is_null(<span>$value</span>)) { <span>// 値がある場合値が空の場合</span><span>//キャッシュを削除</span><span>if</span>(<span>false</span> !== strpos(<span>$name</span>,<span>'*'</span>)){ <span>// 保存されたファイルに * 記号がある場合オブジェクト、エラー</span> <span>return</span><span>false</span> <span>// TODO</span>; }<span>他</span>{ <span>unset</span>(<span>$_cache</span>[<span>$name</span>]);<span>//データキャッシュを削除</span><span>return</span> ThinkStorage::unlink(<span>$filename</span>,<span>'F'</span>); <span>//データファイルを削除 } } </span>他<span> { ThinkStorage::put(</span>$filename<span>,serialize(</span>$value<span>),</span>'F'<span>); </span>//シリアル化を使用してファイルを書き込みます<span></span>//データをキャッシュします<span></span>$_cache<span>[</span>$ name<span>] = </span>$value<span>; </span>// そしてキャッシュに書き込みます <span></span>return<span></span>null<span>; } } </span>// キャッシュ データを取得します <span></span>if<span> (</span>isset<span>(</span>$_cache<span>[</span>$name<span>])) </span>// 一般的な C の <span></span>return<span></span>$_cache<span>[</span>$name] と非常によく似ています<span>]; </span>if<span> (ThinkStorage::has(</span>$filename<span>,</span>'F'<span>)){ </span>// 既存のファイルを読み取ります<span></span>$value<span> = unserialize(ThinkStorage::read(</span>$filename<span>,</span>' F' <span>)); </span>$_cache<span>[</span>$name<span>] = </span>$value<span>// データを返す</span>; } <span>他</span> { <span>$value</span> = <span>false</span>; } <span>return</span><span>$value</span> <span>//データを返す</span>; } <span>// これは単なるキャッシュされたデータの読み取りであり、ファイルよりもはるかに悪いです </span><span>// さて、親愛なる生徒の皆さん、続けてください </span><span>// ここで注意してください、フレームワーク内のファイルは、アプリケーションでは function.php と呼ばれます。 function.php</span><span>と呼ばれる// 今話しているアプリケーション内の場所がわかりますか?</span><span>// 関数のコメントとして、この手紙は簡潔かつ明確です </span><span>/*** 時間 (マイクロ秒) とメモリ使用量のログと統計 * 説明書: * <コード> * G('begin'); // 記録開始マークビット * // ...インターバル実行コード * G('end'); // レコード終了タグビット * echo G('begin','end',6); // 統計的な間隔の実行時間、小数点以下 6 桁までの精度、数値で表した時間 * echo G('begin','end','m'); //統計的な間隔のメモリ使用量、メモリは m で表されます。 ※エンドマークビットが定義されていない場合は、現在のマークビットが自動的に使用されます。 * 統計メモリ使用量を有効にするには、MEMORY_LIMIT_ON 定数が true である必要があります。 * </コード> *<span> @param</span> string $start 開始タグ *<span> @param</span> string $end 終了タグ *<span> @param</span> 整数|文字列 $dec 小数点または m *<span> @return</span> 混合*/</span><span>// ここで言わなければならないのは、thinkphp の創設者は特に何かをするのが好きだということです。入力パラメーターが異なれば、意味も異なります </span><span>// たとえば、C 関数と F 関数では、パラメーターが 1 つだけ入力された場合、それは数値の読み取りを意味し、2 つのパラメーターは値の設定を意味し、3 つのパラメーターは通常、デフォルト値を追加します </span><span> / /number_format — 桁区切り記号を使用して数値をフォーマットします</span><span>// $nombre_format_francais =number_format($number, 2, ',', ' ');</span><span><span>function</span><span>G</span><span>(<span>$start</span>, <span>$end </span>=<span>''</span>,<span>$dec</span>=<span>4</span>)</span> {</span><span>static</span><span>$_info</span> = <span>array</span>() <span>// これは時間倉庫です </span><span>static</span><span>$_mem </span> = <span>array</span>(); <span>// これはメモリ倉庫です </span><span>if</span>(is_float(<span>$end</span>)) { <span>// レコード時間が G('start',2342353234.453); として渡される場合、 Record 上記のスタイルと一貫性を保ちます</span><span>// 小数が渡されると終了します</span><span>$_info</span>[<span>$start</span>] = <span>$end</span>// または、渡された値が次のような場合 G( '開始',microtime(TRUE ));<span> }</span>elseif<span>(!</span>empty<span>(</span>$end<span>)){ </span>// 時間とメモリ使用量の統計。つまり、デフォルトの優先順位は時間です<span></span>// 数字以外の末尾がある場合、その差分が返されます<span></span>if<span> (!</span>isset<span>(</span>$_info<span>[</span>$end<span>])) </span>$_info<span>[</span>$end<span>] = microtime(</span>TRUE<span>); </span>if<span>(MEMORY_LIMIT_ON && </span>$dec<span>==</span>'m'<span>){ </span>// メモリログがオンになっており、明らかにメモリ記録である場合 <span></span>if<span>(!</span>isset<span>(</span>$_mem<span>[ </span>$ end<span>])) </span>$_mem<span>[</span>$end<span>] =memory_get_usage(); </span>// メモリレコードを取得します <span></span>return<span>number_format((</span>$_mem<span>[</span>$end<span>]-</span>$_mem) <span>[</span> $start<span>])/</span>1024<span>); </span>// 返されるフォーマットされた値を取得します<span> }</span>他<span>{ </span>return<span>number_format((</span>$_info<span>[</span>$end<span>]-</span>$_info<span>[</span>$start<span>]),</span>$dec<span>); デフォルトは10進数の4桁です。場所</span> } }<span>else</span>{ <span>//時間とメモリ使用量を記録します</span><span>// メモリと時間フラグを個別に同期的に記録します。</span><span>$_info</span>[<span>$start</span>] = microtime(<span>TRUE</span>); <span>if</span>(MEMORY_LIMIT_ON) <span>$_mem</span>[<span>$start</span>] =memory_get_usage(); } <span>return</span><span>null</span>; } <span>// H機能はありません</span><span>// 今朝のインタビューは以上です、ありがとうございました! </span><span>// さて、昨日は少し焦りましたが、実はこのGは時間とメモリを記録する関数です </span><span>// 記録された時間であるかどうかを区別します。または他のものですが、何があっても、時間は同時にメモリに記録されます</span><span>// 時間とメモリの記録は、ある角度から PHP プログラムのパフォーマンスを反映できます</span><span>// 次は、デフォルト値</span><span>/*** 入力パラメータを取得し、フィルタリングとデフォルト値をサポートします * 説明書: * <コード> * I('id',0); id パラメータを取得し、get または post を自動的に決定します // そうですね、あなたが挙げたこれらの例は実際に非常に一般的に使用されています。 * I('post.name','','htmlspecialchars'); $_POST['name'] を取得します。 * I('get.'); $_GET を取得します。 * </コード> *<span> @param</span> string $name 変数の名前は指定された型をサポートします *<span> @param</span>mixed $default 存在しない場合のデフォルト値 *<span> @param</span> 混合 $filter パラメータ フィルタリング メソッド *<span> @param</span>mixed $datas 取得する追加のデータ ソース *<span> @return</span> 混合*/</span><span><span>function</span><span>I</span><span>(<span>$name</span>,<span>$default</span>=<span>''</span>,<span>$filter</span>=)をサポートする強力なI入力フィルター関数null,<span>$datas</span>=null )</span> {</span><span>// 最初のステップ: ウェアハウスを指定します </span><span>static</span><span>$_PUT</span> = <span>null</span>// デフォルトの単一データ ウェアハウス <span></span>;入力の型を決定する <span></span>if<span>(strpos (</span>$name<span>,</span>'/'<span>)){ </span>//修飾子を指定する<span></span>list<span>(</span>$name<span>,</span>$type<span>) =explode(</span>'/ '<span>,</span>$name<span>,</span> 2<span>); }</span>elseif<span>(C(</span>'VAR_AUTO_STRING'<span>)){ </span>// 文字列へのデフォルトの強制変換<span></span>// // 入力変数を自動的に強制的に文字列に変換するかどうか。有効な場合は、配列変数を強制的に変換する必要があります。変数の変更で手動で渡される シンボルは変数を取得します <span></span>// 実際、上記のデフォルト値は false です<span></span>$type<span> = </span>'s'<span>; } </span>// 第 3 ステップ: データ ソースを取得する <span></span>// 第 3 ステップ: 最初の小さなステップ: データ ソースを分解する <span></span>// 一般的なプログラムでは、上記 2 つは使用されません。つまり、データ型を指定します。デフォルトでは指定されていません。</span><span>if</span>(strpos(<span>$name</span>,<span>'.'</span>)) { <span>//パラメータソースを指定</span><span>list</span>(<span>$method</span>,<span>$name</span>) =explode(<span>'.'</span>, <span>$name</span>,<span>2</span>); }<span>else</span>{ <span>//デフォルトは自動判定</span><span>$method</span> = <span>'param'</span>; } <span>// 3 番目のステップ: 2 番目の小さなステップ: データ ソースを関連付ける </span><span>// データ ソースを指定します。一般的に使用されるのは get post です </span><span>switch</span>(strto lower(<span>$method</span>)) { <span>// 実際にはこれは非常に古典的に使用され、比較前に小文字になります</span><span>case</span><span>'get'</span>: <span>$input</span> =& <span>$_GET</span>; <span>// アドレスの取得も非常に便利で、非常に考えられています </span><span>break</span>; <span>ケース</span><span>「投稿」</span> : <span>$input</span> =& <span>$_POST</span>; <span>休憩</span>; <span>ケース</span><span>「置く」</span> : <span>if</span>(is_null(<span>$_PUT</span>)){ parse_str(file_get_contents(<span>'php://input'</span>), <span>$_PUT</span>); } <span>$input</span> = <span>$_PUT</span>; <span>/* POSTデータの読み取り multipart/form-data 型では使用できません php://input VS $HTTP_RAW_POST_DATA POST データの読み取り */</span><span>break</span>; <span>case</span><span>'param'</span> :<span>// 実際、これは遅延プログラミングと互換性を持たせるためには、</span><span>switch</span>(<span>$_SERVER</span>[<span>'REQUEST_METHOD'</span>]) { <span>ケース</span><span>「投稿」</span>: <span>$input</span> = <span>$_POST</span>; <span>休憩</span>; <span>ケース</span><span>「PUT」</span>: <span>if</span>(is_null(<span>$_PUT</span>)){ parse_str(file_get_contents(<span>'php://input'</span>), <span>$_PUT</span>); } <span>$input</span> = <span>$_PUT</span>; <span>休憩</span>; <span>デフォルト</span>: <span>$input</span> = <span>$_GET</span>; } <span>休憩</span>; <span>// 一般的に使用される 3 つの入力取得メソッド GET POST PUT</span><span>case</span><span>'path'</span> : <span>// 実際にはパス取得がありますが、これは呼び出しで使用したことはありません</span><span>$input</span> = <span>array</span>() ; <span>if</span>(!<span>空</span>(<span>$_SERVER</span>[<span>'PATH_INFO'</span>])){ <span>$depr</span> = C(<span>'URL_PATHINFO_DEPR'</span>);<span>// パス区切り文字 </span><span>//'URL_PATHINFO_DEPR' => '/', // PATHINFO モードでは、各パラメータ間の区切り記号 </span><span>$ input</span> = explode(<span>$depr</span>,trim(<span>$_SERVER</span>[<span>'PATH_INFO'</span>],<span>$depr</span>)); } <span>休憩</span>; <span>ケース</span><span>「リクエスト」</span> : <span>$input</span> =& <span>$_REQUEST</span>; <span>休憩</span>; <span>ケース</span><span>「セッション」</span> : <span>$input</span> =& <span>$_SESSION</span>; <span>休憩</span>; <span>ケース</span><span>「クッキー」</span> : <span>$input</span> =& <span>$_COOKIE</span>; <span>休憩</span>; <span>ケース</span><span>「サーバー」</span> : <span>$input</span> =& <span>$_SERVER</span>; <span>休憩</span>; <span>ケース</span><span>「グローバル」</span> : <span>$input</span> =& <span>$GLOBALS</span>; <span>休憩</span>; <span>ケース</span><span>「データ」</span> : <span>$input</span> =& <span>$datas</span>; <span>休憩</span>; <span>デフォルト</span>: <span>return</span><span>null</span>; } <span>// ステップ 4: 変数を明確に取得する </span><span>// 4.1 すべての値を取得する </span><span>if</span>(<span>''</span>==<span>$name</span>) { <span>// すべての変数を取得する </span><span>$data</span> = <span>$入力</span>; <span>// フィルター関数でフィルター処理を続行します </span><span>$filters</span> = <span>isset</span>(<span>$filter</span>)?<span>$filter</span>:C(<span>'DEFAULT_FILTER'</span>); <span>if</span>(<span>$フィルター</span>) { <span>if</span>(is_string(<span>$フィルター</span>)){ <span>$filters</span> = 爆発(<span>','</span>,<span>$filters</span>); } <span>foreach</span>(<span>$フィルター</span><span>として</span><span>$フィルター</span>){ <span>$data</span> = array_map_recursive(<span>$filter</span>,<span>$data</span>); <span>// パラメータフィルタリング</span> } } <span>// 4.2 指定された値を取得する</span> }<span>elseif</span>(<span>isset</span>(<span>$input</span>[<span>$name</span>])) { <span>// 値が指定されている場合の値演算 </span><span>$data</span> = <span>$input</span>[<span>$name</span>] <span> / /データ取得完了</span><span>//フィルタリング開始</span><span>$filters</span> = <span>isset</span>(<span>$filter</span>)?<span>$filter</span>:C(<span>'DEFAULT_FILTER'</span>); <span>// フィルターが存在します</span><span>if</span>(<span>$filters</span>) { <span>if</span>(is_string(<span>$フィルター</span>)){ <span>if</span>(<span>0</span> === strpos(<span>$filters</span>,<span>'/'</span>)){ <span>if</span>(<span>1</span> !== preg_match(<span>$filters</span>,(string)<span>$data</span>)){ <span>// フィルターは正規表現をサポートします</span><span>// 正規表現の検証をサポートします</span><span>return</span><span>isset</span>( <span> $default</span>) ? <span>$default</span> : <span>null</span>; } }<span>他</span>{ <span>$filters</span> = 爆発(<span>','</span>,<span>$filters</span>); } }<span>elseif</span>(is_int(<span>$filters</span>)){ <span>$filters</span> = <span>array</span>(<span>$filters</span>); } <span>// 配列フィルタリングを実行します</span><span>if</span>(is_array(<span>$filters</span>)){ <span>foreach</span>(<span>$フィルター</span><span>として</span><span>$フィルター</span>){ <span>if</span>(function_exists(<span>$filter</span>)) { <span>$data</span> = is_array(<span>$data</span>) ? array_map_recursive(<span>$filter</span>,<span>$data</span>) : <span>$filter</span>(<span>$data</span>) <span>//パラメータフィルタリング</span> }<span>他</span>{ <span>$data</span> = filter_var(<span>$data</span>,is_int(<span>$filter</span>) ? <span>$filter</span> : filter_id(<span>$filter</span>)); <span>if</span>(<span>false</span> === <span>$data</span>) { <span>return</span><span>isset</span>(<span>$default</span>) : <span>null</span>; } } } } } <span>// デフォルトの string</span><span>if</span>(!<span>empty</span>(<span>$type</span>)){ <span>スイッチ</span>(strto lower(<span>$type</span>)){ <span>case</span><span>'a'</span>: <span>// array</span><span>$data</span> = (<span>array</span>)<span>$data</span>; <span>休憩</span>; <span>case</span><span>'d'</span>: <span>// Number</span><span>$data</span> = (int)<span>$data</span>; <span>休憩</span>; <span>case</span><span>'f'</span>: <span>// 浮動小数点</span><span>$data</span> = (float)<span>$data</span>; <span>休憩</span>; <span>case</span><span>'b'</span>: <span>// Boolean</span><span>$data</span> = (boolean)<span>$data</span>; <span>休憩</span>; <span>case</span><span>の'</span>: <span>// string </span><span>default</span>: <span>$data</span> = (文字列)<span>$data</span>; } } <span>//4.3 デフォルト値を取得する</span> }<span>else</span>{ <span>// 変数のデフォルト値</span><span>$data</span> = <span>isset</span>(<span>$default</span>)?<span>$default</span>:<span>null</span>; } <span>// 最後に、データを返す前にデータが処理されます。つまり、データが配列の場合は、デフォルトのフィルター関数が実行されます</span> is_array(<span>$data</span>) && array_walk_recursive(<span>$data</span>,<span>'think_filter'</span>); <span>リターン</span><span>$データ</span>; } <span>// 要約すると、実際、上記の関数の分析後、おおよそ次のように学習できます: </span><span>// 最初: 最初のステップと同様のステップで分岐コードを作成します: 1.1 1.2 2 番目のステップ: 2.1 2.2 Likeこれ </span><span>// 2 つ目: パラメーター調整による出力の特徴は、さまざまなパラメーターのスタイルに互換性があることです</span><span>// 3 つ目: さまざまなフィルター関数の便利な組み合わせです。とてもいいです! </span><span>// 私はあなたのことを楽観視しています、ハハ! </span><span>// J 関数はありません </span><span>// K 関数はありません </span><span>// この L 関数に遭遇した場合、通常は言語設定に使用されます。</span><span>/*** 言語定義の取得と設定 (大文字と小文字は区別されません) *<span> @param</span> string|array $name 言語変数 *<span> @param</span> 混合 $value 言語値または変数 *<span> @return</span> 混合*/</span><span><span>function</span><span>L</span><span>(<span>$name</span>=null, <span>$value</span>=null)</span> {</span><span>static</span><span>$_lang</span> = <span>array</span>() ;<span>//古いペース、倉庫を定義します</span><span>// 空のパラメーターはすべての定義を返します</span><span>// 3 つの方法</span><span>// 最初の方法: empty</span><span>if</span> (<span>empty</span>(<span>$name</span>) ) <span>/ /古いペース: 入力しないとすべてが返されます</span><span>return</span><span>$_lang</span>; <span>// 言語の取得 (または設定) を決定します </span><span>// 存在しない場合は、すべて大文字の $name を直接返します</span><span>// 文字列の場合 </span><span>// 2 番目の方法: 文字列は次に分割されます空の配列であり、デフォルトで記録されます ここでの戻り値は実際にはアーティファクトです </span><span>if</span> (is_string(<span>$name</span>)) { <span>// 文字列の場合 </span><span>$name</span> = strtoupper(<span>$name</span>) ; <span>// ステップ 1: すべて大文字に変換する </span><span>if</span> (is_null(<span>$value</span>)){ <span>// </span><span>return</span><span>isset</span>(<span>$_lang</span>[<span>$name] を設定するか読み取るかを決定する</span>]) ? <span>$_lang</span> [<span>$name</span>] : <span>$name</span>; 定義がある場合は、定義を返します <span> }</span>elseif<span>(is_array(</span>$value<span>)){ </span>// 配列の場合 <span></span>// 変数をサポート <span></span>$replace<span> = array_keys(</span>$value<span>) </span>// 内のすべてのキー名を返します。配列 新しい配列: <span></span>foreach<span>(</span>$replace<span></span>as<span> &</span>$v<span>){ </span>// このセクションは理解できませんでした。下の階で返事してください!ありがとうございます <span></span>$v<span> = </span>'{$'<span>.</span>$v<span>.</span>'}'<span>; } </span>return<span> str_replace(</span>$replace<span>,</span>$value<span>,</span>isset<span>(</span>$_lang<span>[</span>$name<span>]) ? </span>$_lang<span>[</span>$name<span>] : </span>$name<span>); } </span>$_lang<span>[</span>$name<span>] = </span>$value<span>// 言語定義 それ以外の場合は、</span><span>return</span><span>null</span>; } <span>// バッチ定義 </span><span>// 3 番目の方法: array </span><span>if</span> (is_array(<span>$name</span>)) <span>// バッチ定義 array_change_key_case() 関数は、配列のすべてのキーを大文字または小文字に変換します。デフォルトの大文字 </span><span>$_lang</span> = array_merge(<span>$_lang</span>, array_change_key_case(<span>$name</span>, CASE_UPPER)); <span>return</span><span>null</span>; } <span>// 特によく使われる関数ですが、後ほどD関数をお勧めしますが、どの関数にもそれぞれ特徴があります</span><span>/*** モデル ファイルを使用せずにモデルをインスタンス化します。 *</span> @param<span> string $name モデル名は、MongoModel:User などの基本モデルの指定をサポートします *<span> @param</span> string $tablePrefix テーブル プレフィックス *<span> @param</span> $connection データベース接続情報が混在 *<span> @return</span> ThinkModel*/<span></span>//</span><span></span>function<span><span>M</span><span>( </span> $name<span>=<span>''</span>, <span>$tablePrefix</span>=<span>''</span>,<span>$connection</span>=<span>''</span>)<span> {</span></span>static</span><span>$_model</span> = <span>array</span>();<span>// immutablewarehouse </span><span>if</span>(strpos(<span>$name</span>,<span>':'</span>)) { <span>// コードを結合してクラスに結合し、その後にクラス名 </span><span>list</span>(<span>$ class</span>,<span>$ name</span>) =explode(<span>':'</span>,<span>$name</span>); }<span>他</span>{ <span>$class</span> = <span>'Think\Model'</span>// それ以外の場合は、デフォルトの Model クラスのインスタンス化を実行します<span>; } </span>// これは、一意の値<span></span>$guid<span> = (is_array(</span>$connection<span>)?implode(</span>''<span>,</span>$connection<span>):</span>$connection<span>).</span>$tablePrefix<span>を作成することと同等です。 </span>$名前<span> . </span>'_'<span> 。 </span>if<span> (!</span>isset<span>(</span>$_model<span>[</span>$guid<span>])) </span>// 単一列単一列<span></span>$_model<span>[</span>$guid<span>] = </span>new<span></span>$class<span>(</span>$ name<span> ,</span>$tablePrefix<span>,</span>$connection<span>); </span>// 保存された単一列をインスタンス化します <span></span>return<span></span>$_model<span>[</span>$guid<span>]; これについてはこれ以上は言いません。それでおしまい。</span> } <span>/*** 統計の設定と取得 * 説明書: * <コード> * N('db',1); // データベース操作の数を記録します。 * N('read',1); // 読み取り数を記録します。 * echo N('db') // 現在のページ データベースの操作数を取得します。 * echo N('read'); // 現在のページが読み取られた回数を取得します。 * </コード> *<span> @param</span> 文字列 $key は場所を識別します *<span> @param</span> 整数 $step ステップ値 *<span> @param</span> boolean $save 結果を保存するかどうか *<span> @return</span> 混合*/</span><span><span>function</span><span>N</span><span>(<span>$key</span>, <span>$step</span>=<span>0</span>,<span>$save</span>=false)</span> {</span><span>static</span><span>$_num</span> = <span>array</span>(); <span>// Warehouse</span><span>if</span> (!<span>isset</span>(<span>$_num</span>[<span>$key</span>])) { <span>// 現在の値 </span><span>$_num</span>[<span> $key の場合] </span>] = (<span>false</span> !== <span>$save</span>)? S(<span>'N_'</span>.<span>$key</span>) : <span>0</span>// ストレージが設定されている場合は、S 関数内にあります。処理を実行します。それ以外の場合は 0 になります<span> } </span>if<span> (</span>empty<span>(</span>$step<span>)){ </span>//ステップ設定がない場合<span></span>return<span></span>$_num<span>[</span>$key<span>]; }</span>else<span>{ </span>// それ以外の場合は、ステップウェイ<span></span>$_num<span>[</span>$key<span>] = </span>$_num<span>[</span>$key<span>] + (int)</span>$step<span>; } </span>if<span>(</span>false<span> !== </span>$save<span>){ </span>// 実際には、これはキャッシュ読み取り関数を使用します。 <span> S(</span>'N_'<span>.</span>$key<span>,</span>$_num<span>[</span>$key<span>],</span>$save<span>); } </span>return<span></span>null<span>; } </span>// O 関数はありません <span></span>// P 関数はありません <span></span>// Q 関数はありません <span></span>// 今日はこれで終わりです。 L M N 関数言語パッケージ M について説明します。インスタンス化では、インスタンス化クラスと接続されたオブジェクトを指定できます。データベース N. ステップの記録 <span></span>// 申し訳ありませんが、昨日は更新がなく、今日のみ更新されました<span></span>/**※コントローラの操作メソッドをリモート呼び出し URLパラメータ形式 [resource://][module/]controller/operation *<span> @param<span> string $url 呼び出し元アドレス *</span> @param<span> string|array $vars 呼び出しパラメータは文字列と配列をサポートします *</span> @param<span> string $layer 呼び出されるコントロール層の名前 *</span> @return<span> 混合*/</span></span>// クエリ文字列を変数に解析します<span></span> // parse_str() 関数はクエリを解析します。文字列は変数に解析されます。 <span></span> // 注: php.ini ファイル内の magic_quotes_gpc 設定は、この関数の出力に影響します。有効にすると、変数は parse_str() によって解析される前に addslashes() によって変換されます。 <span></span>/**parse_str("名前=ビル&年齢=60"); echo $name."<br>"; エコー $age; * parse_str("name=Bill&age=60",$myArray); print_r($myArray);*/<span></span>// print_r(pathinfo("/testweb/test.txt"));<span></span>// pathinfo() はパス情報を含む連想配列を返します。 <span></span>/**配列 ( [ディレクトリ名] => /テストウェブ [ベース名] =>テスト.txt [拡張子] => TXT ) * [ディレクトリ名] [ベース名] [拡大]*/<span></span>/**クラスクラスA { 関数 bc($b, $c) { $bc = $b + $c; $bc をエコーします。 } } call_user_func_array(array('ClassA','bc'), array("111", "222")); //表示 333*/<span></span><span>function<span></span>R<span></span>(<span>$url<span>,</span>$vars<span>=array</span>()<span>,</span>$layer<span> =</span>''<span>)</span> {</span></span>$info<span> = pathinfo(</span>$url<span>); </span>// パスを解析します <span></span>$action<span> [</span>'basename'<span>]; Name</span><span>$module</span> = <span>$info</span>[<span>'dirname'</span>]; <span>// ファイルパスを取得します </span><span>$class</span> = A(<span>$module</span>,<span>$layer</span>);実際のクラス Widget などの追加レベルの関係をインスタンス化します<span></span>if<span>(</span>$class<span>){ </span>// クラスがある場合<span></span>if<span>(is_string(</span>$vars<span>)) { </span>// がある場合渡される変数<span> parse_str(</span>$vars<span>,</span>$vars<span>); </span>// 受信パラメータを配列に解析します<span> } </span>return<span> call_user_func_array(</span>array<span>(&</span>$class<span>,</span>$action<span>.C(</span>'ACTION_SUFFIX'<span>)),</span>$vars<span>); }</span>他<span>{ </span>return<span></span>false<span>; } } </span>// 要約すると、実際、この R は call_user_func_array のアップグレードされたバージョンであり、URL を通じて直接処理されます。 <span></span>//残り1時間半。今日も勉強を続けてください<span></span>// この関数は実はとてもすごい関数だそうです。この2つのゴーストの違いを比較してみましょう。<span>/*** キャッシュ管理 *<span> @param</span> 混合 $name キャッシュ名 (キャッシュ設定が配列表現の場合) *<span> @param</span> 混合 $value キャッシュ値 *<span> @param</span> 混合 $options キャッシュ パラメーター *<span> @return</span> 混合*/</span><span><span>function</span><span>S</span><span>(<span>$name</span>,<span>$value</span>=<span>''</span>,<span>$options</span>=null)</span> {</span><span>static</span><span>$キャッシュ</span> = <span>''</span>; <span>// 倉庫倉庫 倉庫は倉庫です </span><span>// 最初のステップ: 初期化 </span><span>if</span>(is_array(<span>$options</span>)){ <span>// キャッシュパラメータが実際にbit messy type どこにでも置けます </span><span> // キャッシュ中の初期化は実際には初期化プロセスです </span><span>$type</span> = <span>isset</span>(<span>$options</span>[<span>'type'</span>])?<span>$options</span>[ <span>'タイプ'</span>]:<span>''</span>; <span>$cache</span> = ThinkCache::getInstance(<span>$type</span>,<span>$options</span>); }<span>elseif</span>(is_array(<span>$name</span>)) { <span>// キャッシュの初期化 // キャッシュパラメータが実際には少し乱雑な場合は、任意の位置に配置できます </span><span>$type</span> = <span>isset</span>(<span>$ name</span>[<span> 'type'</span>])?<span>$name</span>[<span>'type'</span>]:<span>''</span>; <span>$cache</span> = ThinkCache::getInstance(<span>$type</span>,<span>$name</span>); <span>リターン</span><span>$キャッシュ</span>; }<span>elseif</span>(<span>empty</span>(<span>$cache</span>)) { <span>//自動初期化 まだ完了していない場合</span><span>$cache</span> = ThinkCache::getInstance() <span>//初期化</span>; } <span>// データを元にデザインする </span><span>if</span>(<span>''</span>=== <span>$value</span>){ <span>// キャッシュを取得</span><span>return</span><span>$cache</span>->get(<span>$name</span>); <span>//データを取得する</span> }<span>elseif</span>(is_null(<span>$value</span>)) { <span>//キャッシュを削除</span><span>return</span><span>$cache</span>->rm(<span>$name</span>); <span>//データを削除 }</span>else<span> { </span>// キャッシュデータ <span></span>if<span>(is_array(</span>$options<span>)) { </span>$expire<span> = </span>isset<span>(</span>$options<span>[</span>'expire'<span>])?</span>$options<span>[</span>'expire'<span>]:</span>NULL<span>; }</span>他<span>{ </span>$expire<span> = is_numeric(</span>$options<span>)?</span>$options<span>:</span>NULL<span>; } </span>return<span></span>$cache<span>->set(</span>$name<span>, </span>$value<span>, </span>$expire<span>); </span>// データを保存します<span> } } </span>// 要約すると、これは実際何のためにあるのでしょうか? 重要なのはクラス関数です <span></span>// 実際、その関数はもう何の意味もありません <span></span>// 今日、私は新しいことを学びました、それはテンプレート エンジンを書くことです <span> </span>/*** テンプレートファイル形式の取得 resource://module@theme/controller/operation *<span> @param<span> string $template テンプレート リソース アドレス *</span> @param<span> string $layer ビュー レイヤ (ディレクトリ) 名 *</span> @return<span> 文字列*/</span></span><span>function<span></span>T<span></span>(<span>$template<span>=</span>''<span>,</span>$layer<span>=</span>''<span>)</span>{</span></span>//解析の最初のステップテンプレートリソースのアドレス: <span></span> if<span>(</span>false<span> === strpos(</span>$template<span>,</span>'://'<span>)){ </span>$template<span> = </span>'http://'<span>.str_replace(</span>':'<span>, </span>'/'<span>,</span>$template<span>); } </span>$info<span> = parse_url(</span>$template<span>); </span>// ステップ 2: 独自の配列に解析する <span></span>$file<span> = </span>$info<span>[</span>'host'<span>].(</span>isset<span>(</span> $info) <span>[</span>'パス'<span>])?</span>$info<span>[</span>'パス'<span>]:</span>''<span>); </span>$module<span> = </span>isset<span>(</span>$info<span>[</span>'user'<span>])?</span>$info<span>[</span>'user'<span>].</span>'/'<span>:MODULE_NAME.</span>'/'<span>/ / extensusername</span><span>$ extend =</span>$ info [<span>'scheme'</span>]; ); <span>// レベル </span><span>// 現在のテーマのテンプレート パスを取得します </span><span>$auto</span> = C(<span>'AUTOLOAD_NAMESPACE'</span>); if<span>(</span>$auto<span>&&</span>isset<span>(</span>$auto<span>[</span>$extend<span>])){</span>//拡張リソース<span></span>$baseurl<span>=</span>$auto<span>[</span>$extend<span>].</span>$モジュール<span>.</span>$layer<span>.</span>'/'<span>; }</span>elseif<span>(C(</span>'VIEW_PATH'<span>)){ </span>//モジュールビューディレクトリを変更<span></span>$baseUrl<span> = C(</span>'VIEW_PATH'<span>); }<span>elseif</span>(定義(<span>'TMPL_PATH'</span>)){ <span>//グローバルビューディレクトリを指定</span><span>$baseUrl</span> = TMPL_PATH.<span>$module</span>; }<span>他</span>{ <span>$baseUrl</span> = APP_PATH.<span>$module</span>.<span>$layer</span>.<span>'/'</span>; } <span>// テーマを取得</span><span>$theme</span> = substr_count(<span>$file</span>,<span>'/'</span>)<<span>2</span> ? C(<span>'DEFAULT_THEME'</span>) : <span>''</span>; <span>//分析テンプレートファイルのルール</span><span>$depr</span> = C(<span>'TMPL_FILE_DEPR'</span>); <span>if</span>(<span>''</span> == <span>$file</span>) { <span>// テンプレート ファイル名が空の場合は、デフォルトのルール </span><span>$file</span> = <span>$depr</span> に従って検索します。 }<span>elseif</span>(<span>false</span> === strpos(<span>$file</span>, <span>'/'</span>)){ <span>$file</span> = CONTROLLER_NAME . <span>$depr</span> 。 }<span>elseif</span>(<span>'/'</span> != <span>$depr</span>){ <span>$file</span> = substr_count(<span>$file</span>,<span>'/'</span>)><span>1</span> ? substr_replace(<span>$file</span>,<span>$depr</span>,strrpos(<span>$file</span>,<span>'/'</span>), <span>1</span>) : str_replace(<span>'/'</span>, <span>$depr</span>, <span>$file</span>); } <span>return</span><span>$baseUrl</span>.(<span>$theme</span>?<span>$theme</span>.<span>'/'</span>:<span>''</span>).<span>$file</span>.C(<span>'TMPL_TEMPLATE_SUFFIX'</span>); } <span>// 要約すると、実際、この製品は実際の URL パスを返すだけです</span><span>// 今日はこの新しいもの、組み立てられた製品です</span><span>/** * URL アセンブリはさまざまな URL パターンをサポートします *</span> @param<span> string $url URL 式、形式: '[モジュール/コントローラー/オペレーション#アンカー@ドメイン名]?パラメーター1=値1&パラメーター2=値2...' *<span> @param</span> string|array $vars はパラメーターで渡され、配列と文字列をサポートします *<span> @param</span> string|boolean $suffix 擬似静的サフィックス、デフォルトは設定値を取得するための true です *<span> @param</span> boolean $domain ドメイン名を表示するかどうか *<span> @return</span> 文字列 * この関数は、指定された URL の有効性を検証するために使用されるのではなく、URL を以下にリストされている部分に分割するためにのみ使用されます。不完全な URL も受け入れられ、parse_url() はそれらをできるだけ正確に解析しようとします。*配列 ( [スキーム] => [ホスト] => ホスト名 [ユーザー] => ユーザー名 [パス] => パスワード [パス] => /パス [クエリ] => arg=疑問符の後の値 ? [フラグメント] => ハッシュ記号 # の後のアンカー ) * $url = 'http://ユーザー名:パスワード@ホスト名/パス?arg=値#アンカー'; */</span><span><span>function</span><span>U</span><span>(<span>$url</span>=<span>''</span>,<span>$vars</span>=<span>''</span>,<span>$suffix</span>=true,<span>$domain</span>=false)</span> {</span><span> // URL を解析します。実際、ここで渡された URL は通常のアドレスの URL ではありません。個人的には、これはあまり科学的ではないと思います。 </span>$url<span>); </span>//ここで解析パラメータを解析します。方法は通常のものと同じではありません<span></span>// 状況 1<span></span>// $url = 'Home/Index/index#zhangsan@www.maizi. net?name=lisi&age=32';<span></span>// var_dump(parse_url ($url));<span></span>//array (size=2)<span></span>//'path' => (length=16)<span></span>// 'fragment' => string 'zhangsan@www.maizi.net?name=lisi&age=32' (length=39)<span></span>// ケース 2<span></span>// $url = ' Home/Index/index@www.maizi.net?name=lisi&age= 32';<span></span>// var_dump(parse_url($url));<span></span>// array (size=2)<span></span>// 'path' = > 文字列 'Home/Index/index@www.maizi.net' (長さ=30)<span></span>// 'クエリ' => 文字列 'name=lisi&age=32' (長さ=16)<span></span>$url<span> = !</span>empty<span>(</span>$info<span>[</span>'path'<span>] )?</span>$info<span>[</span>'path'<span>]:ACTION_NAME </span>// パスが解析された場合は解析されたパスを使用し、それ以外の場合は action_name を使用します<span> </span>if<span>(</span>isset<span>(</span>$info<span>[</span>' フラグメント'<span>])) { </span>// 解析アンカー ポイントは、Web ページ上の固定位置にジャンプする Web ページ内のマークです <span></span>$anchor<span> = </span>$info<span>[</span>'fragment'<span>]; </span>// 実際には、これはすべて '[モジュール/コントローラー/アクション#アンカー@ドメイン名]?parameter1=value1¶meter2=value2...'<span></span>if<span>( </span>false<span> !== strpos(</span>$anchor<span>,</span>' ?'<span>)) { </span>// アンカーの後に次のパラメータがある場合はパラメータを解析します <span></span>list<span>(</span>$anchor<span>,</span>$info<span>[</span> 'クエリ'<span>]) =explode(</span>'?'<span> ,</span>$anchor<span>,</span>2<span>); } </span>if<span>(</span>false<span> !== strpos(</span>$anchor<span>,</span>'@'<span>)) { </span>// ドメイン名を解析後、アンカー後に@ドメイン名があれば、<span></span>list<span>(</span>$アンカー<span>,</span> $host<span>) =explode(</span>'@'<span>,</span>$anchor<span>, </span>2<span>); } }</span>elseif<span>(</span>false<span> !== strpos(</span>$url<span>,</span>'@'<span>)) { </span>//ドメイン名を解決し、ユーザー名とパスワードをドメイン名から分離します<span></span>list<span>(</span>$ url<span>,</span> $host<span>) =explode(</span>'@'<span>,</span>$info<span>[</span>'path'<span>], </span>2<span>); </span>// '[モジュール/コントローラ/オペレーション@ドメイン名]? パラメータ 1=値 1&パラメータ 2=値 2...' これは不完全です<span> } </span>// サブドメイン名のホストはドメイン名です <span></span>if<span>(</span>isset<span>(</span>$host<span>)) { </span>// 実際、通常の状況では、これは第 2 レベルのドメイン名ではありませんか?はそんなことはありません <span></span>// 実際、この使い方は奇妙です。通常は $domain = $host です。ここではパラメータ <span></span>$domain<span> = </span>$host<span> が続く場合があります。(strpos(</span>$host<span>, </span>'.'<span>)?</span>''<span>: strstr(</span>$_SERVER<span>[</span>'HTTP_HOST'<span>],</span>'.'<span>)); }<span>elseif</span>(<span>$domain</span>===<span>true</span>){ <span>//表示されたドメイン名が追加された場合、それは真のブール型ではありません </span><span>$domain</span> = <span>$_SERVER</span>[<span>'HTTP_HOST' </span>]; <span>//ホスト名とドメイン名を表示します </span><span>if</span>(C(<span>'APP_SUB_DOMAIN_DEPLOY'</span>) ) { <span>// サブドメイン展開の有効化はデフォルトでは有効になっていません </span><span>$domain</span> = <span>$domain</span>= =<span>' localhost'</span>?<span>'localhost'</span>:<span>'www'</span>.strstr(<span>$_SERVER</span>[<span>'HTTP_HOST'</span>],<span>'.'</span>// デフォルトでは、www.your ドメイン名前は彼のためにキャッシュされます ローカルのものは無視します<span></span> // 'サブドメイン名'=>array('Module[/controller]'); 実際には、それは使用されない可能性があります<span></span>。 foreach<span> (C( </span>'APP_SUB_DOMAIN_RULES'<span>) </span>as<span></span>$key<span> => </span>$rule<span>) {</span>// サブドメインルールを処理しています<span></span>$rule<span> = is_array(</span>$rule<span>)?</span>$ルール<span>[</span>0 <span>]:</span>$ルール<span>; </span>if<span>(</span>false<span> === strpos(</span>$key<span>,</span>'*'<span>) && </span>0<span>=== strpos(</span>$url<span>,</span>$rule<span>)) { </span>$domain<span> = </span>$key<span>.strstr(</span>$domain<span>,</span>'.'<span>); </span>// 対応するサブドメインを生成します <span></span>$url<span> = substr_replace(</span>$url<span>,</span>''<span>,</span>) 0<span>,strlen(</span>$rule<span>)); </span>休憩<span>; } } } } </span>// パラメータを解析します パラメータを解析します。これは後で渡されるパラメータです<span></span>if<span>(is_string(</span>$vars<span>)) { </span>// aaa=1&bbb=2 を配列に変換します<span> parse_str(</span>$vars<span>,</span>$vars<span>); }</span>elseif<span>(!is_array(</span>$vars<span>)){ </span>$vars<span> = </span>array<span>(); } </span>// パラメータをマージします <span></span>if<span>(</span>isset<span>(</span>$info<span>[</span>'query'<span>])) { </span>// アドレス内のパラメータを解析し、vars にマージします<span> parse_str(</span>$info<span>[</span>'クエリ'<span>],</span>$params<span>); </span>$vars<span> = array_merge(</span>$params<span>,</span>$vars<span>); } </span>// ここで要約すると、実際には大規模なステップです。最初のステップは分割です <span></span>// 2 番目のステップ: アセンブリ <span></span>// URL アセンブリ <span></span>$depr<span> = C(</span>'URL_PATHINFO_DEPR'<span>) ; </span>/ /'/', // PATHINFO モードでは、各パラメーター間の分離記号 <span></span>$urlCase<span> = C(</span>'URL_CASE_INSENSITIVE'<span>) </span>//// デフォルトの false は URL が大文字と小文字を区別することを意味します。大文字と小文字を区別しないことを意味します <span></span>// URL アドレスがある場合 <span></span>if<span>(</span>$url<span>) { </span>if<span>(</span>0<span>=== strpos(</span>$url<span>,</span>'/'<span>)) {</span>// ルート定義 ディレクトリの場合 <span></span>$route<span> = </span>true<span>; </span>$url<span> = substr(</span>$url<span>,</span>1<span>); </span>// 最初のスラッシュを削除します <span></span>if<span>(</span>'/'<span> != </span>$depr<span>) { </span>// 指定されたシステムに変更します間隔記号 <span></span>$url<span> = str_replace(</span>'/'<span>,</span>$depr<span>,</span>$url<span>); } }</span>else<span>{ </span>// つまり、ルートディレクトリではない場合 <span></span>if<span>(</span>'/'<span> != </span>$depr<span>) { </span>// 安全な置換<span></span>$url<span> = str_replace(</span>) ' /'<span>,</span>$depr<span>,</span>$url<span>); }<span>// モジュール、コントローラー、オペレーションを解析します </span><span>$url</span> = trim(<span>$url</span>,<span>$depr</span>); <span>// 両端のスペーサー記号を削除します </span><span>$path</span> =explode(<span>$depr</span>) , <span>$url</span>); <span>// パスを解析します </span><span>$var</span> = <span>array</span>(); <span>$varModule</span> = C(<span>'VAR_MODULE'</span>); <span>// 'VAR_MODULE' => 'm', // デフォルトモジュールは変数を取得します </span><span>$varController</span> = C(<span>'VAR_CONTROLLER'</span>); 'VAR_CONTROLLER' => 'c', // デフォルトのコントローラーは変数を取得します <span></span>$varAction<span> = C(</span>'VAR_ACTION'<span>); </span>// 'VAR_ACTION' => 'a', // デフォルトのアクションを取得します変数 <span></span>$var<span>[</span>$varAction<span>] = !</span>empty<span>(</span>$path<span>)?array_pop(</span>$path<span>):ACTION_NAME </span>// このようにアクション<span></span>$var<span>を解析します。 [</span>$varController<span>] = !</span>empty<span>(</span>$path<span>)?array_pop(</span>$path<span>):CONTROLLER_NAME;</span>// 解析する場合は上記と同じ <span></span>if<span>(</span>$maps<span> = C(</span>' URL_ACTION_MAP' <span>)) { </span>// デフォルトではルーティング ルールが定義されていないため、ここでは実行されません<span></span>if<span>(</span>isset<span>(</span>$maps<span>[strto lower(</span>$var<span>[</span>$varController<span>] ) ])) { </span>$maps<span> = </span>$maps<span>[strto lower(</span>$var<span>[</span>$varController<span>])]; </span>if<span>(</span>$action<span> = array_search(strto lower(</span>$var<span>[</span>$varAction<span>]),</span>$maps<span>)){ </span>$var<span>[</span>$varAction<span>] = </span>$action<span>; } } } </span>if<span>(</span>$maps<span> = C(</span>'URL_CONTROLLER_MAP'<span>)) { </span>// 同上<span></span>// $a=array("a"=>"red","b"=> "green ","c"=>"blue");<span></span>// echo array_search("red",$a);<span></span>if<span>(</span>$controller<span> = array_search(strto lower(</span>$var<span>[</span> $varController <span>]),</span>$maps<span>)){ </span>$var<span>[</span>$varController<span>] = </span>$controller<span>; } } </span>if<span>(</span>$urlCase<span>) { </span>//大文字と小文字を区別するかどうかに関係なく、デフォルトは true であり、区別されないことを意味します <span></span>$var<span>[</span>$varController<span>] = parse_name(</span>$var<span>) [</span>$varController<span>]); </span> //すべてを統一フォーマットに変換します<span> } </span>$module<span> = </span>''<span>; </span>//空に初期化<span></span>if<span>(!</span>empty<span>(</span>$path<span>)) { </span>//パスが空でない場合<span></span>$var<span>[</span>$ varModule <span>] = implode(</span>$depr<span>,</span>$path<span>); }</span>他<span>{ </span>if<span>(C(</span>'MULTI_MODULE'<span>)) { </span>// 複数のモジュールが有効な場合 // 複数のモジュールを許可するかどうか。 false の場合、DEFAULT_MODULE<span></span>if<span>(MODULE_NAME != C(</span>) 'DEFAULT_MODULE'<span>) || !C(</span>'MODULE_ALLOW_LIST'<span>)){ </span>$var<span>[</span>$varModule<span>]= MODULE_NAME; } } } </span>それ <span>])、</span>$マップ<span>)){ </span>$var<span>[</span>$varModule<span>] = </span>$_module<span>; } } </span>if<span>(</span>isset<span>(</span>$var<span>[</span>$varModule<span>])){ </span>// 同上<span></span>$module<span> = </span>$var<span>[</span>$varModule<span>]; </span>設定解除<span>(</span>$var<span>[</span>$varModule<span>]); } } } </span>// 実際、本当の組み合わせはここから始まります <span></span>// ドメイン名 <span></span>//<span></span>if<span>(C(</span>'URL_MODEL'<span>) == </span>0<span>) { </span>// 通常モード URL 変換 <span></span>$url<span> = __APP__.</span>'?'<span>.C(</span>'VAR_MODULE'<span>).</span>"={$module}&"<span>.http_build_query(array_reverse(</span>$var<span>)); </span>if<span>(</span>$urlCase<span>){ </span>//すべてを小文字に変換します<span></span>$url<span> = strto lower(</span>$url<span>); } </span>if<span>(!</span>empty<span>(</span>$vars<span>)) { </span>// パラメータが空でない場合は、パラメータを追加します <span></span>$vars<span> = http_build_query(</span>$vars<span>); </span>$url<span> .= </span>'&'<span>.</span>$vars<span>; } }<span>else</span>{ <span>// PATHINFO モードまたは互換 URL モード </span><span>if</span>(<span>isset</span>(<span>$route</span>)) {<span>// ルーティングが有効な場合 </span><span>$url</span> = __APP__.<span>'/'</span>. rtrim(<span>$url</span>,<span>$depr</span>); }<span>他</span>{ <span>$module</span> = (定義(<span>'BIND_MODULE'</span>) && BIND_MODULE==<span>$module</span> )? <span>$url</span> = __APP__.<span>'/'</span>.(<span>$module</span>?<span>$module</span>.MODULE_PATHINFO_DEPR:<span>''</span>).implode(<span>$depr</span>,array_reverse(<span>$var</span>)); } <span>if</span>(<span>$urlCase</span>){ <span>// 変換</span><span>$url</span> = strto lower(<span>$url</span>); } <span>if</span>(!<span>empty</span>(<span>$vars</span>)) { <span>// パラメータを解析する別の方法</span><span>foreach</span> (<span>$vars</span><span>as</span><span>$var</span> => <span>$val </span>){ <span>if</span>(<span>''</span> !== トリム(<span>$val</span>)) <span>$url</span> .= <span>$var</span> . urlencode(<span>$val</span>); } } <span>if</span>(<span>$suffix</span>) {<span>// ファイルサフィックスが定義されている場合 </span><span>$suffix</span> = <span>$suffix</span>===<span>true</span>?C(<span>'URL_HTML_SUFFIX'</span>):<span>$suffix </span>; <span>if</span>(<span>$pos</span> = strpos(<span>$suffix</span>, <span>'|'</span>)){ <span>$suffix</span> = substr(<span>$suffix</span>, <span>0</span>, <span>$pos</span>); } <span>if</span>(<span>$suffix</span> && <span>'/'</span> != substr(<span>$url</span>,-<span>1</span>)){ <span>$url</span> .= <span>'.'</span>.ltrim(<span>$suffix</span>,<span>'.'</span>); } } } <span>if</span>(<span>isset</span>(<span>$anchor</span>)){ <span>// アンカーポイントがある場合は </span><span>$url</span> .= <span>'#'</span>.<span>$anchor</span>; を結合します。 } <span>if</span>(<span>$domain</span>) { <span>// ドメイン名を結合します </span><span>$url</span> = (is_ssl()?<span>'https://'</span>:<span>'http://'</span>).<span>$domain </span> .<span>$url</span>; } <span>戻る</span><span>$url</span>; } ... Method<span></span>// 一般的に使用されるメソッドは U('Home/Index/index',array('name'=>'lijingshan','age'=>'12'));<span></span>/ / デフォルトでは、ドメイン名とアンカーの使い方がわかりませんが、この 2 つはまだ優れています (笑)、解析するのは複雑ではありませんが、組み合わせると、ルーティング ルールが少し面倒になります。 <span></span>// さて、今日も続きます <span></span>// この関数は実際にはパッケージです <span></span>/*** レンダリング出力ウィジェット *<span> @param</span> string $name ウィジェット名 *<span> @param</span> 配列 $data がパラメータで渡されました *<span> @return</span> void*/<span></span><span>function</span><span>W</span><span>(</span>$name<span>, <span>$data</span> =array <span>()</span>)<span> {</span></span>return<span> R(<span>$name</span>,<span>$data</span>,<span>'ウィジェット'<span>); } </span>//いいえ * リソースアドレスを解析し、クラスライブラリファイルをインポートします * 例: module/controller addon://module/behavior *<span></span></span></span></span></span></span></span></code>