<div class="article-view">
<div class="view-body think-editor-content"><p>在Web開發過程中,我們經常需要獲取系統變量或者用戶提交的數據,這些變量數據錯綜復雜,而且一不小心就容易引起安全隱患,但是如果利用好ThinkPHP提供的變量獲取功能,就可以輕松的獲取和駕馭變量了。</p>
<h2 id="u83B7u53D6u53D8u91CF">獲取變量</h2>
<p>雖然你仍然可以在開發過程中使用傳統方式獲取各種系統變量,例如:</p>
<pre><code class="hljs php"><span class="hljs-variable">$id</span> = <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'id'</span>]; <span class="hljs-comment">// 獲取get變量</span>
<span class="hljs-variable">$name</span> = <span class="hljs-variable">$_POST</span>[<span class="hljs-string">'name'</span>]; <span class="hljs-comment">// 獲取post變量</span>
<span class="hljs-variable">$value</span> = <span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'var'</span>]; <span class="hljs-comment">// 獲取session變量</span>
<span class="hljs-variable">$name</span> = <span class="hljs-variable">$_COOKIE</span>[<span class="hljs-string">'name'</span>]; <span class="hljs-comment">// 獲取cookie變量</span>
<span class="hljs-variable">$file</span> = <span class="hljs-variable">$_SERVER</span>[<span class="hljs-string">'PHP_SELF'</span>]; <span class="hljs-comment">// 獲取server變量</span></code></pre>
<p>但是我們不建議直接使用傳統方式獲取,因為沒有統一的安全處理機制,后期如果調整的話,改起來會比較麻煩。所以,更好的方式是在框架中統一使用I函數進行變量獲取和過濾。</p>
<p><span class="e-search-highlight" rel="mark">I方法</span>是ThinkPHP用于更加方便和安全的獲取系統輸入變量,可以用于任何地方,用法格式如下:</p>
<pre><code class="hljs bash">I(<span class="hljs-string">'變量類型.變量名/修飾符'</span>,[<span class="hljs-string">'默認值'</span>],[<span class="hljs-string">'過濾方法或正則'</span>],[<span class="hljs-string">'額外數據源'</span>])</code></pre>
<p>變量類型是指請求方式或者輸入類型,包括:</p>
<table>
<thead>
<tr>
<th>變量類型</th>
<th>含義</th>
</tr>
</thead>
<tbody>
<tr>
<td>get</td>
<td>獲取GET參數</td>
</tr>
<tr>
<td>post</td>
<td>獲取POST參數</td>
</tr>
<tr>
<td>param</td>
<td>自動判斷請求類型獲取GET、POST或者PUT參數</td>
</tr>
<tr>
<td>request</td>
<td>獲取REQUEST 參數</td>
</tr>
<tr>
<td>put</td>
<td>獲取PUT 參數</td>
</tr>
<tr>
<td>session</td>
<td>獲取 $_SESSION 參數</td>
</tr>
<tr>
<td>cookie</td>
<td>獲取 $_COOKIE 參數</td>
</tr>
<tr>
<td>server</td>
<td>獲取 $_SERVER 參數</td>
</tr>
<tr>
<td>globals</td>
<td>獲取 $GLOBALS參數</td>
</tr>
<tr>
<td>path</td>
<td>獲取 PATHINFO模式的URL參數</td>
</tr>
<tr>
<td>data</td>
<td>獲取 其他類型的參數,需要配合額外數據源參數</td>
</tr>
</tbody>
</table>
<blockquote class="default">
<p>注意:變量類型不區分大小寫,變量名則嚴格區分大小寫。 <br>
默認值和過濾方法均屬于可選參數。</p>
</blockquote>
<p>我們以GET變量類型為例,說明下<span class="e-search-highlight" rel="mark">I方法</span>的使用:</p>
<pre><code class="hljs bash"><span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.id'</span>); // 相當于 <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'id'</span>]
<span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.name'</span>); // 相當于 <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>]</code></pre>
<p>支持默認值:</p>
<pre><code class="hljs bash"><span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.id'</span>,<span class="hljs-number">0</span>); // 如果不存在<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'id'</span>] 則返回<span class="hljs-number">0</span>
<span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.name'</span>,<span class="hljs-string">''</span>); // 如果不存在<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>] 則返回空字符串</code></pre>
<p>采用方法過濾:</p>
<pre><code class="hljs bash">// 采用htmlspecialchars方法對<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>] 進行過濾,如果不存在則返回空字符串
<span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.name'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">'htmlspecialchars'</span>); </code></pre>
<p>支持直接獲取整個變量類型,例如:</p>
<pre><code class="hljs bash">// 獲取整個<span class="hljs-variable">$_GET</span> 數組
I(<span class="hljs-string">'get.'</span>); </code></pre>
<p>用同樣的方式,我們可以獲取post或者其他輸入類型的變量,例如:</p>
<pre><code class="hljs ruby"><span class="hljs-constant">I</span>(<span class="hljs-string">'post.name'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">'htmlspecialchars'</span>); <span class="hljs-regexp">//</span> 采用htmlspecialchars方法對<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'name'</span>] 進行過濾,如果不存在則返回空字符串
<span class="hljs-constant">I</span>(<span class="hljs-string">'session.user_id'</span>,<span class="hljs-number">0</span>); <span class="hljs-regexp">//</span> 獲取<span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'user_id'</span>] 如果不存在則默認為<span class="hljs-number">0</span>
<span class="hljs-constant">I</span>(<span class="hljs-string">'cookie.'</span>); <span class="hljs-regexp">//</span> 獲取整個 <span class="hljs-variable">$_COOKIE</span> 數組
<span class="hljs-constant">I</span>(<span class="hljs-string">'server.REQUEST_METHOD'</span>); <span class="hljs-regexp">//</span> 獲取 <span class="hljs-variable">$_SERVER</span>[<span class="hljs-string">'REQUEST_METHOD'</span>] </code></pre>
<p>param變量類型是框架特有的支持自動判斷當前請求類型的變量獲取方式,例如:</p>
<pre><code class="hljs bash"><span class="hljs-built_in">echo</span> I(<span class="hljs-string">'param.id'</span>);</code></pre>
<p>如果當前請求類型是GET,那么等效于 $_GET['id'],如果當前請求類型是POST或者PUT,那么相當于獲取 $_POST['id'] 或者 PUT參數id。</p>
<p>由于param類型是I函數默認獲取的變量類型,因此事實上param變量類型的寫法可以簡化為:</p>
<pre><code class="hljs go">I(<span class="hljs-string">'id'</span>); <span class="hljs-comment">// 等同于 I('param.id')</span>
I(<span class="hljs-string">'name'</span>); <span class="hljs-comment">// 等同于 I('param.name')</span></code></pre>
<p>path類型變量可以用于獲取URL參數(必須是PATHINFO模式參數有效,無論是GET還是POST方式都有效),例如: 當前訪問URL地址是 <code>http://serverName/index.php/New/2013/06/01</code></p>
<p>那么我們可以通過</p>
<pre><code class="hljs cs"><span class="hljs-function">echo <span class="hljs-title">I</span>(<span class="hljs-params"><span class="hljs-string">'path.1'</span></span>)</span>; <span class="hljs-comment">// 輸出2013</span>
<span class="hljs-function">echo <span class="hljs-title">I</span>(<span class="hljs-params"><span class="hljs-string">'path.2'</span></span>)</span>; <span class="hljs-comment">// 輸出06</span>
<span class="hljs-function">echo <span class="hljs-title">I</span>(<span class="hljs-params"><span class="hljs-string">'path.3'</span></span>)</span>; <span class="hljs-comment">// 輸出01</span></code></pre>
<p>data類型變量可以用于獲取不支持的變量類型的讀取,例如:</p>
<pre><code class="hljs bash">I(<span class="hljs-string">'data.file1'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-variable">$_FILES</span>);</code></pre>
<h2 id="u53D8u91CFu8FC7u6EE4">變量過濾</h2>
<p>如果你沒有在調用I函數的時候指定過濾方法的話,系統會采用默認的過濾機制(由DEFAULT_FILTER配置),事實上,該參數的默認設置是:</p>
<pre><code class="hljs php"><span class="hljs-comment">// 系統默認的變量過濾機制</span>
<span class="hljs-string">'DEFAULT_FILTER'</span> => <span class="hljs-string">'htmlspecialchars'</span></code></pre>
<p>也就說,<span class="e-search-highlight" rel="mark">I方法</span>的所有獲取變量如果沒有設置過濾方法的話都會進行htmlspecialchars過濾,那么:</p>
<pre><code class="hljs bash">// 等同于 htmlspecialchars(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>])
I(<span class="hljs-string">'get.name'</span>); </code></pre>
<p>同樣,該參數也可以設置支持多個過濾,例如:</p>
<pre><code class="hljs php"><span class="hljs-string">'DEFAULT_FILTER'</span> => <span class="hljs-string">'strip_tags,htmlspecialchars'</span></code></pre>
<p>設置后,我們在使用:</p>
<pre><code class="hljs bash">// 等同于 htmlspecialchars(strip_tags(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>]))
I(<span class="hljs-string">'get.name'</span>); </code></pre>
<p>如果我們在使用<span class="e-search-highlight" rel="mark">I方法</span>的時候 指定了過濾方法,那么就會忽略DEFAULT_FILTER的設置,例如:</p>
<pre><code class="hljs bash">// 等同于 strip_tags(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'name'</span>])
<span class="hljs-built_in">echo</span> I(<span class="hljs-string">'get.name'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">'strip_tags'</span>); </code></pre>
<p><span class="e-search-highlight" rel="mark">I方法</span>的第三個參數如果傳入函數名,則表示調用該函數對變量進行過濾并返回(在變量是數組的情況下自動使用<code>array_map</code>進行過濾處理),否則會調用PHP內置的<code>filter_var</code>方法進行過濾處理,例如:</p>
<pre><code class="hljs bash">I(<span class="hljs-string">'post.email'</span>,<span class="hljs-string">''</span>,FILTER_VALIDATE_EMAIL);</code></pre>
<p>表示 會對<code>$_POST['email']</code> 進行 格式驗證,如果不符合要求的話,返回空字符串。 (關于更多的驗證格式,可以參考 官方手冊的<code>filter_var</code>用法。) 或者可以用下面的字符標識方式:</p>
<pre><code class="hljs bash">I(<span class="hljs-string">'post.email'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">'email'</span>);</code></pre>
<p>可以支持的過濾名稱必須是<code>filter_list</code>方法中的有效值(不同的服務器環境可能有所不同),可能支持的包括:</p>
<pre><code class="hljs cs"><span class="hljs-keyword">int</span>
boolean
<span class="hljs-keyword">float</span>
validate_regexp
validate_url
validate_email
validate_ip
<span class="hljs-keyword">string</span>
stripped
encoded
special_chars
unsafe_raw
email
url
number_int
number_float
magic_quotes
callback</code></pre>
<p>還可以支持進行正則匹配過濾,例如:</p>
<pre><code class="hljs cs"><span class="hljs-comment">// 采用正則表達式進行變量過濾</span>
I(<span class="hljs-string">'get.name'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">'/^[A-Za-z]+$/'</span>);
I(<span class="hljs-string">'get.id'</span>,<span class="hljs-number">0</span>,<span class="hljs-string">'/^\d+$/'</span>);</code></pre>
<p>如果正則匹配不通過的話,則返回默認值。</p>
<p>在有些特殊的情況下,我們不希望進行任何過濾,即使<strong>DEFAULT_FILTER</strong>已經有所設置,可以使用:</p>
<pre><code class="hljs cs"><span class="hljs-comment">// 下面兩種方式都不采用任何過濾方法</span>
I(<span class="hljs-string">'get.name'</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>);
I(<span class="hljs-string">'get.id'</span>,<span class="hljs-string">''</span>,<span class="hljs-keyword">false</span>);</code></pre>
<p>一旦過濾參數設置為空字符串或者false,即表示不再進行任何的過濾。</p>
<h2 id="u53D8u91CFu4FEEu9970u7B26">變量修飾符</h2>
<p>最新版本的I函數支持對變量使用修飾符功能,可以更方便的通過類型過濾變量。</p>
<p>用法如下: </p>
<pre><code class="hljs bash">I(<span class="hljs-string">'變量類型.變量名/修飾符'</span>)</code></pre>
<p>例如:</p>
<pre><code class="hljs go">I(<span class="hljs-string">'get.id/d'</span>); <span class="hljs-comment">// 強制變量轉換為整型</span>
I(<span class="hljs-string">'post.name/s'</span>); <span class="hljs-comment">// 強制轉換變量為字符串類型</span>
I(<span class="hljs-string">'post.ids/a'</span>); <span class="hljs-comment">// 強制變量轉換為數組類型</span></code></pre>
<p>可以使用的修飾符包括: </p>
<table>
<thead>
<tr>
<th>修飾符</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>s</td>
<td>強制轉換為字符串類型</td>
</tr>
<tr>
<td>d</td>
<td>強制轉換為整型類型</td>
</tr>
<tr>
<td>b</td>
<td>強制轉換為布爾類型</td>
</tr>
<tr>
<td>a</td>
<td>強制轉換為數組類型</td>
</tr>
<tr>
<td>f</td>
<td>強制轉換為浮點類型</td>
</tr>
</tbody>
</table></div>
<div class="view-foot">
<div class="article-jump">
<span class="jump-up" style="display: none;">上一篇:<a data-articleid="1712" href="/manual/thinkphp/1712">控制器</a></span>
<span class="jump-down" style="display: none;">下一篇:<a data-articleid="1714" href="/manual/thinkphp/1714">前置和后置操作</a></span>
</div>
<a class="view-backtop"><i class="icon-arrow-up2"></i></a>
</div>
</div>