# 快速入門(十一):擴展
`ThinkPHP5`對擴展的支持更加方便和靈活,`5.0`版本的擴展原則是不在核心目錄添加任何擴展和文件,以確保核心框架的更新。
- - [函數擴展](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/197464#u51FDu6570u6269u5C55)
- [類庫擴展](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/197464#u7C7Bu5E93u6269u5C55)
- [驅動擴展](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/197464#u9A71u52A8u6269u5C55)
- [Composer擴展](http://www.hmoore.net/thinkphp/thinkphp5_quickstart/197464#composer-)
## 函數擴展
如果要擴展自己的全局自定義函數,或者重寫系統的助手函數,可以直接在應用目錄下面的`common.php`文件(`application/common.php`)中定義,例如:
```
<pre class="calibre18">
```
<span class="hljs-comment">// 增加一個新的table助手函數</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">table</span><span class="hljs-number">(<span class="hljs-regexp">$table</span>, <span class="hljs-regexp">$config</span> = [])</span></span>{
<span class="hljs-keyword">return</span> \think\Db::connect(<span class="hljs-regexp">$config</span>)->setTable(<span class="hljs-regexp">$table</span>);
}
<span class="hljs-comment">// 替換框架內置的db助手函數</span><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">db</span><span class="hljs-number">(<span class="hljs-regexp">$name</span>, <span class="hljs-regexp">$config</span> = [])</span></span>{
<span class="hljs-keyword">return</span> \think\Db::connect(<span class="hljs-regexp">$config</span>)->name(<span class="hljs-regexp">$name</span>);
}
```
```
如果只是定義某個模塊需要使用的函數,則可以放到模塊的公共文件中,例如定義`index`模塊使用的函數可以在`application/index/common.php`中。
## 類庫擴展
如果你需要在核心之外擴展和使用第三方類庫,并且該類庫不是通過`Composer`安裝使用,那么可以直接放入應用根目錄下面的`extend`目錄下面,該目錄是官方建議的第三方擴展類庫目錄。
`extend`目錄下面的類庫必須遵循`PSR-4`自動加載規范,系統會按照目錄自動注冊命名空間,下面是一個`org\util\ArrayList`類:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">org</span>\<span class="hljs-title">util</span>;
<span class="hljs-comment">/**
* ArrayList實現類
* <span class="hljs-operator">@author</span> liu21st <liu21st<span class="hljs-operator">@gmail</span>.com>
*/</span><span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">ArrayList</span> <span class="hljs-keyword">implements</span> \<span class="hljs-title">IteratorAggregate</span></span>{
<span class="hljs-comment">/**
* 集合元素
* <span class="hljs-operator">@var</span> array
* <span class="hljs-operator">@access</span> protected
*/</span><span class="hljs-keyword">protected</span> <span class="hljs-regexp">$elements</span> = [];
<span class="hljs-comment">/**
* 架構函數
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> string $elements 初始化數組元素
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span><span class="hljs-number">(<span class="hljs-regexp">$elements</span> = [])</span></span>{
<span class="hljs-keyword">if</span> (!<span class="hljs-keyword">empty</span>(<span class="hljs-regexp">$elements</span>)) {
<span class="hljs-regexp">$this</span>->elements = <span class="hljs-regexp">$elements</span>;
}
}
<span class="hljs-comment">/**
* 若要獲得迭代因子,通過getIterator方法實現
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@return</span> ArrayObject
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getIterator</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> \ArrayObject(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 增加元素
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> mixed $element 要添加的元素
* <span class="hljs-operator">@return</span> boolean
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span><span class="hljs-number">(<span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-keyword">return</span> (array_push(<span class="hljs-regexp">$this</span>->elements, <span class="hljs-regexp">$element</span>)) ? <span class="hljs-keyword">true</span> : <span class="hljs-keyword">false</span>;
}
<span class="hljs-comment">// 在數組開頭插入一個單元</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">unshift</span><span class="hljs-number">(<span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-keyword">return</span> (array_unshift(<span class="hljs-regexp">$this</span>->elements, <span class="hljs-regexp">$element</span>)) ? <span class="hljs-keyword">true</span> : <span class="hljs-keyword">false</span>;
}
<span class="hljs-comment">// 將數組最后一個單元彈出(出棧)</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pop</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> array_pop(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 增加元素列表
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> ArrayList $list 元素列表
* <span class="hljs-operator">@return</span> boolean
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addAll</span><span class="hljs-number">(<span class="hljs-regexp">$list</span>)</span></span>{
<span class="hljs-regexp">$before</span> = <span class="hljs-regexp">$this</span>->size();
<span class="hljs-keyword">foreach</span> (<span class="hljs-regexp">$list</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$element</span>) {
<span class="hljs-regexp">$this</span>->add(<span class="hljs-regexp">$element</span>);
}
<span class="hljs-regexp">$after</span> = <span class="hljs-regexp">$this</span>->size();
<span class="hljs-keyword">return</span> (<span class="hljs-regexp">$before</span> < <span class="hljs-regexp">$after</span>);
}
<span class="hljs-comment">/**
* 清除所有元素
* <span class="hljs-operator">@access</span> public
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">clear</span><span class="hljs-number">()</span></span>{
<span class="hljs-regexp">$this</span>->elements = [];
}
<span class="hljs-comment">/**
* 是否包含某個元素
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> mixed $element 查找元素
* <span class="hljs-operator">@return</span> string
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">contains</span><span class="hljs-number">(<span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-keyword">return</span> (array_search(<span class="hljs-regexp">$element</span>, <span class="hljs-regexp">$this</span>->elements) !== <span class="hljs-keyword">false</span>);
}
<span class="hljs-comment">/**
* 根據索引取得元素
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> integer $index 索引
* <span class="hljs-operator">@return</span> mixed
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get</span><span class="hljs-number">(<span class="hljs-regexp">$index</span>)</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$this</span>->elements[<span class="hljs-regexp">$index</span>];
}
<span class="hljs-comment">/**
* 查找匹配元素,并返回第一個元素所在位置
* 注意 可能存在0的索引位置 因此要用===False來判斷查找失敗
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> mixed $element 查找元素
* <span class="hljs-operator">@return</span> integer
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">indexOf</span><span class="hljs-number">(<span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-keyword">return</span> array_search(<span class="hljs-regexp">$element</span>, <span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 判斷元素是否為空
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@return</span> boolean
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isEmpty</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">empty</span>(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 最后一個匹配的元素位置
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> mixed $element 查找元素
* <span class="hljs-operator">@return</span> integer
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">lastIndexOf</span><span class="hljs-number">(<span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-keyword">for</span> (<span class="hljs-regexp">$i</span> = (count(<span class="hljs-regexp">$this</span>->elements) - <span class="hljs-number">1</span>); <span class="hljs-regexp">$i</span> > <span class="hljs-number">0</span>; <span class="hljs-regexp">$i</span>--) {
<span class="hljs-keyword">if</span> (<span class="hljs-regexp">$this</span>->get(<span class="hljs-regexp">$i</span>) == <span class="hljs-regexp">$element</span>) {
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$i</span>;
}
}
}
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toJson</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> json_encode(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 根據索引移除元素
* 返回被移除的元素
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> integer $index 索引
* <span class="hljs-operator">@return</span> mixed
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">remove</span><span class="hljs-number">(<span class="hljs-regexp">$index</span>)</span></span>{
<span class="hljs-regexp">$element</span> = <span class="hljs-regexp">$this</span>->get(<span class="hljs-regexp">$index</span>);
<span class="hljs-keyword">if</span> (!is_null(<span class="hljs-regexp">$element</span>)) {
array_splice(<span class="hljs-regexp">$this</span>->elements, <span class="hljs-regexp">$index</span>, <span class="hljs-number">1</span>);
}
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$element</span>;
}
<span class="hljs-comment">/**
* 移出一定范圍的數組列表
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> integer $offset 開始移除位置
* <span class="hljs-operator">@param</span> integer $length 移除長度
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeRange</span><span class="hljs-number">(<span class="hljs-regexp">$offset</span>, <span class="hljs-regexp">$length</span>)</span></span>{
array_splice(<span class="hljs-regexp">$this</span>->elements, <span class="hljs-regexp">$offset</span>, <span class="hljs-regexp">$length</span>);
}
<span class="hljs-comment">/**
* 移出重復的值
* <span class="hljs-operator">@access</span> public
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">unique</span><span class="hljs-number">()</span></span>{
<span class="hljs-regexp">$this</span>->elements = array_unique(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 取出一定范圍的數組列表
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> integer $offset 開始位置
* <span class="hljs-operator">@param</span> integer $length 長度
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">range</span><span class="hljs-number">(<span class="hljs-regexp">$offset</span>, <span class="hljs-regexp">$length</span> = null)</span></span>{
<span class="hljs-keyword">return</span> array_slice(<span class="hljs-regexp">$this</span>->elements, <span class="hljs-regexp">$offset</span>, <span class="hljs-regexp">$length</span>);
}
<span class="hljs-comment">/**
* 設置列表元素
* 返回修改之前的值
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> integer $index 索引
* <span class="hljs-operator">@param</span> mixed $element 元素
* <span class="hljs-operator">@return</span> mixed
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">set</span><span class="hljs-number">(<span class="hljs-regexp">$index</span>, <span class="hljs-regexp">$element</span>)</span></span>{
<span class="hljs-regexp">$previous</span> = <span class="hljs-regexp">$this</span>->get(<span class="hljs-regexp">$index</span>);
<span class="hljs-regexp">$this</span>->elements[<span class="hljs-regexp">$index</span>] = <span class="hljs-regexp">$element</span>;
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$previous</span>;
}
<span class="hljs-comment">/**
* 獲取列表長度
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@return</span> integer
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">size</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> count(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">/**
* 轉換成數組
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@return</span> array
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">toArray</span><span class="hljs-number">()</span></span>{
<span class="hljs-keyword">return</span> <span class="hljs-regexp">$this</span>->elements;
}
<span class="hljs-comment">// 列表排序</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ksort</span><span class="hljs-number">()</span></span>{
ksort(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">// 列表排序</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">asort</span><span class="hljs-number">()</span></span>{
asort(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">// 逆向排序</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rsort</span><span class="hljs-number">()</span></span>{
rsort(<span class="hljs-regexp">$this</span>->elements);
}
<span class="hljs-comment">// 自然排序</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">natsort</span><span class="hljs-number">()</span></span>{
natsort(<span class="hljs-regexp">$this</span>->elements);
}
}</span>
```
```
我們把類文件放到`extend/org/util/ArrayList.php`,就可以直接使用該類了,注意`ArrayList`類的完整命名空間應該是`org\util\ArrayList`,而不是`extend\org\util\ArrayList`,下面我們來寫個例子測試下是否可以正常使用該擴展類庫,控制器代碼如下:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">index</span>\<span class="hljs-title">controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">org</span>\<span class="hljs-title">uitl</span>\<span class="hljs-title">ArrayList</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">Index</span></span>{
<span class="hljs-keyword">public</span> funtion index()
{
<span class="hljs-regexp">$list</span> = [<span class="hljs-string">'thinkphp'</span>, <span class="hljs-string">'thinkphp'</span>, <span class="hljs-string">'onethink'</span>, <span class="hljs-string">'topthink'</span>];
<span class="hljs-regexp">$arrayList</span> = <span class="hljs-keyword">new</span> ArrayList(<span class="hljs-regexp">$list</span>);
<span class="hljs-regexp">$arrayList</span>->add(<span class="hljs-string">'kancloud'</span>);
<span class="hljs-regexp">$arrayList</span>->unique();
dump(<span class="hljs-regexp">$arrayList</span>->toArray());
<span class="hljs-keyword">echo</span> <span class="hljs-regexp">$arrayList</span>->toJson();
}
}</span>
```
```
訪問輸出的結果為:
```
<pre class="calibre18">
```
array (size=4)
<span class="hljs-operator">0 => <span class="hljs-keyword">string</span> <span class="hljs-string">'thinkphp'</span> (<span class="hljs-keyword">length</span>=<span class="hljs-number">8</span>)
<span class="hljs-number">2</span> => <span class="hljs-keyword">string</span> <span class="hljs-string">'onethink'</span> (<span class="hljs-keyword">length</span>=<span class="hljs-number">8</span>)
<span class="hljs-number">3</span> => <span class="hljs-keyword">string</span> <span class="hljs-string">'topthink'</span> (<span class="hljs-keyword">length</span>=<span class="hljs-number">8</span>)
<span class="hljs-number">4</span> => <span class="hljs-keyword">string</span> <span class="hljs-string">'kancloud'</span> (<span class="hljs-keyword">length</span>=<span class="hljs-number">8</span>)
{<span class="hljs-string">"0"</span>:<span class="hljs-string">"thinkphp"</span>,<span class="hljs-string">"2"</span>:<span class="hljs-string">"onethink"</span>,<span class="hljs-string">"3"</span>:<span class="hljs-string">"topthink"</span>,<span class="hljs-string">"4"</span>:<span class="hljs-string">"kancloud"</span>}</span>
```
```
`extend`擴展目錄通常是放一些全局并且和應用無關的公共類庫,如果是應用相關的類庫則可以納入應用目錄,例如:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">common</span>\<span class="hljs-title">util</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">Auth</span></span>{
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> funtion check(<span class="hljs-regexp">$uid</span>)
{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
}
}</span>
```
```
類庫文件位于`application/common/util/Auth.php`。
## 驅動擴展
驅動擴展其實是一種比較特別的類庫擴展而已,因為針對不同的驅動有不同的方法規范,驅動擴展不需要放入核心目錄,你可以在任何位置擴展相關驅動,官方推薦的方式是在`extend`目錄下面的`driver`子目錄放置所有的驅動擴展。
```
<pre class="calibre18">
```
extend/driver
├─cache <span class="hljs-comment">// 緩存擴展驅動目錄</span>
├─db <span class="hljs-comment">// 數據庫擴展驅動目錄</span>
├─debug <span class="hljs-comment">// 調試擴展驅動目錄</span>
├─<span class="hljs-number">log</span> <span class="hljs-comment">// 日志擴展驅動目錄</span>
├─session <span class="hljs-comment">// SESSION擴展驅動目錄</span>
├─<span class="hljs-keyword">template</span> <span class="hljs-comment">// 模板標簽擴展驅動目錄</span>
├─...
```
```
以日志擴展為例,我們來擴展一個日志驅動滿足項目的實際需求,該日志驅動會把指定的日志信息發送到指定郵箱,驅動類實現如下:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">driver</span>\<span class="hljs-title">log</span>;
<span class="hljs-comment">/**
* 本地化調試輸出到文件
*/</span><span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">Email</span></span>{
<span class="hljs-keyword">protected</span> <span class="hljs-regexp">$config</span> = [
<span class="hljs-string">'time_format'</span> => <span class="hljs-string">' c '</span>,
<span class="hljs-string">'email_addr'</span> => <span class="hljs-string">''</span>,
<span class="hljs-string">'send_level'</span> => [<span class="hljs-string">'error'</span>],
];
<span class="hljs-comment">// 實例化并傳入參數</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span><span class="hljs-number">(<span class="hljs-regexp">$config</span> = [])</span></span>{
<span class="hljs-keyword">if</span> (is_array(<span class="hljs-regexp">$config</span>)) {
<span class="hljs-regexp">$this</span>->config = array_merge(<span class="hljs-regexp">$this</span>->config, <span class="hljs-regexp">$config</span>);
}
}
<span class="hljs-comment">/**
* 日志寫入接口
* <span class="hljs-operator">@access</span> public
* <span class="hljs-operator">@param</span> array $log 日志信息
* <span class="hljs-operator">@return</span> bool
*/</span><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">save</span><span class="hljs-number">(array <span class="hljs-regexp">$log</span> = [])</span></span>{
<span class="hljs-regexp">$now</span> = date(<span class="hljs-regexp">$this</span>->config[<span class="hljs-string">'time_format'</span>]);
<span class="hljs-regexp">$info</span> = <span class="hljs-string">''</span>;
<span class="hljs-regexp">$server</span> = <span class="hljs-keyword">isset</span>(<span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'SERVER_ADDR'</span>]) ? <span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'SERVER_ADDR'</span>] : <span class="hljs-string">'0.0.0.0'</span>;
<span class="hljs-regexp">$remote</span> = <span class="hljs-keyword">isset</span>(<span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REMOTE_ADDR'</span>]) ? <span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REMOTE_ADDR'</span>] : <span class="hljs-string">'0.0.0.0'</span>;
<span class="hljs-regexp">$method</span> = <span class="hljs-keyword">isset</span>(<span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REQUEST_METHOD'</span>]) ? <span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REQUEST_METHOD'</span>] : <span class="hljs-string">'CLI'</span>;
<span class="hljs-regexp">$uri</span> = <span class="hljs-keyword">isset</span>(<span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REQUEST_URI'</span>]) ? <span class="hljs-regexp">$_SERVER</span>[<span class="hljs-string">'REQUEST_URI'</span>] : <span class="hljs-string">''</span>;
<span class="hljs-keyword">foreach</span> (<span class="hljs-regexp">$log</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$type</span> => <span class="hljs-regexp">$val</span>) {
<span class="hljs-keyword">if</span> (in_array(<span class="hljs-regexp">$type</span>, <span class="hljs-regexp">$this</span>->config[<span class="hljs-string">'send_level'</span>])) {
<span class="hljs-keyword">foreach</span> (<span class="hljs-regexp">$val</span> <span class="hljs-keyword">as</span> <span class="hljs-regexp">$msg</span>) {
<span class="hljs-keyword">if</span> (!is_string(<span class="hljs-regexp">$msg</span>)) {
<span class="hljs-regexp">$msg</span> = var_export(<span class="hljs-regexp">$msg</span>, <span class="hljs-keyword">true</span>);
}
<span class="hljs-regexp">$info</span> .= <span class="hljs-string">'[ '</span> . <span class="hljs-regexp">$type</span> . <span class="hljs-string">' ] '</span> . <span class="hljs-regexp">$msg</span> . <span class="hljs-string">"<br/>"</span>;
}
}
}
<span class="hljs-keyword">return</span> error_log(<span class="hljs-string">"[{$now}] {$server} {$remote} {$method} {$uri}<div>{$info}</div>"</span>, <span class="hljs-number">1</span>, <span class="hljs-regexp">$this</span>->config[<span class="hljs-string">'email_addr'</span>],<span class="hljs-string">"Subject: Log-{$now}"</span>);
}
}</span>
```
```
然后,修改應用配置文件中的`log`參數為:
```
<pre class="calibre18">
```
<span class="hljs-string">'log'</span> => [
<span class="hljs-string">'type'</span> => <span class="hljs-string">'driver\log\Email'</span>,
<span class="hljs-string">'email_addr'</span> => <span class="hljs-string">'thinkphp@qq.com'</span>,
<span class="hljs-string">'send_level'</span> => [<span class="hljs-string">'error'</span>, <span class="hljs-string">'info'</span>],
],
```
```
為了確保郵件發送正常,你可能還需要配置郵件服務參數,如果是`windows`服務器,配置`php.ini`文件中的相關參數
```
<pre class="calibre18">
```
<span class="hljs-operator">SMTP = <span class="hljs-string">你的smtp服務器host(域名或者IP)</span></span>
<span class="hljs-operator">smtp_port = <span class="hljs-string">端口號(默認<span class="hljs-number">25</span>)</span></span>
<span class="hljs-operator">sendmail_from = <span class="hljs-string"><span class="hljs-operator">"發送郵件的來源信息"</span></span></span>
```
```
如果是`Linux`系統,一般無需配置或者在`php.ini`設置`sendmail_path`參數:
```
<pre class="calibre18">
```
sendmail_path = sendmail 程序的路徑(通常是 <span class="hljs-regexp">/usr/</span>sbin<span class="hljs-regexp">/sendmail 或 /</span>usr<span class="hljs-regexp">/lib/</span>sendmail)
```
```
下面是一個測試例子:
```
<pre class="calibre18">
```
<span class="hljs-operator"><span class="hljs-number"><?php</span><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">index</span>\<span class="hljs-title">controller</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">think</span>\<span class="hljs-title">Log</span>;
<span class="hljs-operator"><span class="hljs-keyword">class</span> <span class="hljs-title">Index</span></span>{
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span><span class="hljs-number">()</span></span>{
Log::error(<span class="hljs-string">'測試錯誤'</span>);
}
}</span>
```
```
當運行后,如果你的郵件服務配置正確,會收到一份郵件通知,否則可能會拋出異常頁面。
## Composer擴展
很多情況下,我們的擴展需要依賴其它的第三方擴展,那么為了有效解決依賴問題,使用Composer擴展包是最方便的開發模式。
關于如何使用`composer`擴展我們會在后面介紹官方擴展的時候給你詳細描述。
- 脕茫隆壟脨貌脩脭
- 脕茫隆壟脨貌脩脭
- 脪祿隆壟祿霉麓隆
- 脪祿隆壟祿霉麓隆
- 露鎂隆壟URL潞脥脗路脫脡
- 露鎂隆壟URL潞脥脗路脫脡
- 脠媒隆壟脟毛脟貿潞脥脧矛脫婁
- 脠媒隆壟脟毛脟貿潞脥脧矛脫婁
- 脣脛隆壟脢媒戮脻驢芒
- 脣脛隆壟脢媒戮脻驢芒
- 脦氓隆壟虜茅脩爐脫茂脩脭
- 脦氓隆壟虜茅脩爐脫茂脩脭
- 脕霉隆壟脛攏脨脥潞脥鹿脴脕陋
- 攏簍1攏漏脛攏脨脥露簍脪氓
- 攏簍2攏漏祿霉麓隆虜脵脳梅
- 攏簍3攏漏露脕脠隆脝梅潞脥脨脼賂脛脝梅
- 攏簍4攏漏脌脿脨脥脳陋祿祿潞脥脳脭露爐脥錨魯脡
- 攏簍5攏漏虜茅脩爐路露脦摟
- 攏簍6攏漏脢盲脠毛潞脥脩茅脰隴
- 攏簍7攏漏鹿脴脕陋
- 攏簍8攏漏脛攏脨脥脢盲魯枚
- 脝脽隆壟脢脫脥錄潞脥脛攏擄氓
- 脝脽隆壟脢脫脥錄潞脥脛攏擄氓
- 擄脣隆壟碌梅脢脭潞脥脠脮脰戮
- 擄脣隆壟碌梅脢脭潞脥脠脮脰戮
- 戮脜隆壟API驢陋路壟
- 戮脜隆壟API驢陋路壟
- 脢廬隆壟脙眉脕卯脨脨鹿隴戮脽
- 脢廬隆壟脙眉脕卯脨脨鹿隴戮脽
- 脢廬脪祿隆壟脌漏脮鹿
- 脢廬脪祿隆壟脌漏脮鹿
- 脢廬露鎂隆壟脭脫脧卯
- Cookie
- Session
- 碌樓脭陋虜芒脢脭
- 脥錄脧帽麓婁脌鉚
- 脦脛錄鎂脡脧麓蘆
- 脩茅脰隴脗毛
- 賂陸脗錄
- A隆壟魯攏錄沒脦脢脤芒錄爐
- B隆壟3.2潞脥5.0脟酶鹵冒
- C隆壟脰煤脢脰潞爐脢媒
- 路盧脥芒脝陋攏潞脩摟脧擄ThinkPHP5碌脛脮媒脠路脳脣脢脝
- 路盧脥芒脝陋攏潞脩摟脧擄ThinkPHP5碌脛脮媒脠路脳脣脢脝