2015年12月28日 星期一

遠振主機 escapeshellarg() has been disabled for security reasons

用遠振主機又踩雷啦,遠振將escapeshellarg這個函式disabled 所以只要有用到 SebastianBergmann\Environment\Runtime Symfony\Component\Console\Input\Input Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser Symfony\Component\Process\ProcessUtils Tracy\Debugger 都會提示 escapeshellarg() has been disabled for security reasons 不過還好php5.3之後就支援namespace,可以讓我們輕鬆略過這個問題 (如果使用的套件不支援namespace那就只好認命的去修改程式囉) 只要require下面的檔案就可以解決這些問題了 ```php namespace Yuan\Jhen { if (function_exists('escapeshellarg') === true) { function escapeshellarg($input) { return \escapeshellarg($input); } } else { function escapeshellarg($input) { $input = str_replace('\'', '\\\'', $input); return '\''.$input.'\''; } } } namespace SebastianBergmann\Environment { function escapeshellarg($input) { return \Yuan\Jhen\escapeshellarg($input); } } namespace Symfony\Component\Console\Input { function escapeshellarg($input) { return \Yuan\Jhen\escapeshellarg($input); } } namespace Symfony\Component\HttpFoundation\File\MimeType { function escapeshellarg($input) { return \Yuan\Jhen\escapeshellarg($input); } } namespace Symfony\Component\Process { function escapeshellarg($input) { return \Yuan\Jhen\escapeshellarg($input); } } namespace Tracy { function escapeshellarg($input) { return \Yuan\Jhen\escapeshellarg($input); } } ```

2015年12月22日 星期二

利用Git來升級Laravel

照著影片操作,就會出現conflicts,處理完conflicts之後,再執行 ```bash composer install ``` 這樣大致上就升級完畢了,而且如果升級出問題還可以利用git本身的功能來進行還原...

2015年12月20日 星期日

php 偵測語系

```php function getDefaultLanguage() { if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { return parseDefaultLanguage($_SERVER['HTTP_ACCEPT_LANGUAGE']); } else { return parseDefaultLanguage(null); } } function parseDefaultLanguage($http_accept, $deflang = 'zh-TW') { if (isset($http_accept) && strlen($http_accept) > 1) { # Split possible languages into array $x = explode(',', $http_accept); foreach ($x as $val) { #check for q-value and create associative array. No q-value means 1 by rule if (preg_match("/(.*);q=([0-1]{0,1}.\d{0,4})/i", $val, $matches)) { $lang[$matches[1]] = (float) $matches[2]; } else { $lang[$val] = 1.0; } } #return default language (highest q-value) $qval = 0.0; foreach ($lang as $key => $value) { if ($value > $qval) { $qval = (float) $value; $deflang = $key; } } } return strtolower($deflang); } echo getDefaultLanguage(); ```

資料庫備份工具

```php class DatabaseClone { public $link; public function __construct($host, $username, $password) { $this->link = mysqli_connect($host, $username, $password); mysqli_query($this->link, 'SET NAMES utf8'); mysqli_query($this->link, 'SET AUTOCOMMIT = 0'); mysqli_query($this->link, 'SET UNIQUE_CHECKS = 0'); mysqli_query($this->link, 'SET FOREIGN_KEY_CHECKS = 0'); } public function fetch($query) { $results = []; $query = mysqli_query($this->link, $query); while ($row = mysqli_fetch_assoc($query)) { $results[] = $row; } return $results; } public function copy($copyTo) { set_time_limit(-1); ini_set('memory_limit', -1); $query = mysqli_query($this->link, $sql = 'show databases'); while ($database = mysqli_fetch_assoc($query)) { $database = $database['Database']; if (in_array($database, ['mysql', 'information_schema', 'performance_schema'], true) === true) { continue; } $createDatabase = mysqli_fetch_assoc(mysqli_query($this->link, 'SHOW CREATE DATABASE `'.$database.'`')); mysqli_query($copyTo->link, $sql = 'DROP DATABASE IF EXISTS `'.$database.'`') or var_dump($sql); mysqli_query($copyTo->link, $sql = $createDatabase['Create Database']) or var_dump($sql); mysqli_select_db($this->link, $database); mysqli_select_db($copyTo->link, $database); $query2 = mysqli_query($this->link, $sql = 'show tables'); while ($table = mysqli_fetch_assoc($query2)) { $table = current($table); $createTable = mysqli_fetch_assoc(mysqli_query($this->link, 'SHOW CREATE TABLE `'.$table.'`')); mysqli_query($copyTo->link, $sql = $createTable['Create Table']) or var_dump($sql); $counts = current(mysqli_fetch_assoc(mysqli_query($this->link, 'SELECT COUNT(*) as counts FROM `'.$table.'`'))); $range = range(0, $counts - 1); $offset = 0; $limit = 200; $chunks = array_chunk($range, $limit); foreach ($chunks as $chunk) { $query3 = mysqli_query($this->link, $sql = 'SELECT * FROM `'.$table.'` LIMIT '.$limit.' OFFSET '.$offset) or var_dump($database, $sql); while ($row = mysqli_fetch_assoc($query3)) { $keys = []; $values = []; foreach ($row as $key => $value) { $keys[] = '`'.$key.'`'; $values[] = "'".addslashes($value)."'"; } mysqli_query($copyTo->link, $sql = 'INSERT INTO `'.$table.'` ('.implode(',', $keys).') VALUES ('.implode(',', $values).')') or var_dump($database, $sql); } $offset += count($chunk); } } } } } $database = new DatabaseClone('localhost:3306', 'root', ''); $database->copy(new DatabaseClone('localhost:3308', 'root', '')); ```

2015年11月7日 星期六

使用instance來進行Tracy Panel

```php // PHP程式碼 include __DIR__.'/vendor/autoload.php'; use Tracy\Debugger; use Tracy\IBarPanel; class CustomPanel implements IBarPanel { /** * Renders HTML code for custom tab. * @return string */ public function getTab() { return 'sql'; } /** * Renders HTML code for custom panel. * @return string */ public function getPanel() { $data = $this->data; ob_start(); require __DIR__.'/custompanel.php'; return ob_get_clean(); } public function push($data) { $this->data[] = $data; } public $data = []; private static $_instance; public static function instance() { if (static::$_instance === null) { static::$_instance = new static; } return static::$_instance; } } // 開發環境 $environment = Debugger::DEVELOPMENT; // 啟用 Debugger::enable($environment); Debugger::getBar() ->addPanel(CustomPanel::instance()); $i = 0; CustomPanel::instance()->push([ 'sql' => 'select * from user where id = '.++$i, ]); CustomPanel::instance()->push([ 'sql' => 'select * from user where id = '.++$i, ]); CustomPanel::instance()->push([ 'sql' => 'select * from user where id = '.++$i, ]); ``` ```php //樣板<h1>SQL</h1>

<div class="tracy-inner">
    <table>
        <?php foreach ($data as $key => $value): ?>
            <tr><td><?php echo $value['sql']; ?></td></tr>
        <?php endforeach ?>
    </table>
</div> ```

2015年10月23日 星期五

Laravel的Session不等於PHP Native Session

在Laravel內我們可能寫了以下的程式碼 ```php get('/session', function () { session_start(); session()->put('foo', 'bar'); $_SESSION['foo'] = 'bar'; header('location: '.url('/session/display')); exit; }); get('/session/display', function () { session_start(); ob_start(); dump(session()->get('foo')); dump($_SESSION['foo']); $content = ob_get_clean(); // output null, 'bar' return $content; }); ``` 會發現輸出結果完全不如我們所預期,為什麼會這樣呢?我們就好好的來做個探討吧... ## 原因出在Laravel的Session根本不是用PHP Native Session 在遇到這個狀況後,於是就去查了一下Laravel Session倒底是怎麼一回事,發現Laravel的程式碼內根本沒有執行session_start()啊 ## Laravel Session倒底是怎麼運作的 追了一下Laravel的原始碼,發現它是利用[Illuminate\Session\Middleware\StartSession](https://github.com/illuminate/session/blob/master/Middleware/StartSession.php)來進行php session模擬的, 在Laravel執行的最後階段在將存在記憶體內的資料進行實體寫入, 所以只要在我們只要在程式內任意一個地方執行了php的exit, die, header('location: xxx'); 那Session就不會被存入檔案內,自然在下一次連線也就取不到值了 ## 有沒有解決方案 有,當然有,只要輸入 ```php get('/session', function () { session_start(); session()->put('foo', 'bar'); $_SESSION['foo'] = 'bar'; session()->save(); // 手動寫入 dump($_SESSION['foo']); $content = ob_get_clean(); // output 'bar', 'bar' return $content; }); ``` ## 後記 為什麼會有這一篇的出現,因為我們可能會用很多其它已經寫好的library,但它們就是有用到session_start();外加header, die, exit等等指令啊,所以記錄一下來提醒自己囉

2015年9月20日 星期日

重寫Laravel Socialite

最近需要用到OAuth的Client套件 所以就使用目前最多人使用的Laravel 不過需要的部份只有Laravel Socialite 看了一下composer.json的相依性 ```json "require": { "php": ">=5.4.0", "illuminate/contracts": "~5.0", "illuminate/http": "~5.0", "illuminate/support": "~5.0", "guzzlehttp/guzzle": "~5.0|~6.0", "league/oauth1-client": "~1.0" }, ``` 只需要這些package並不需要整個Laravel 所以就開始使用它 不過在使用的過程遇到了不少問題 它所需要的package其實不止這些 所以程式在撰寫的過程中確實遇到不少問題 再在上在本機端上開發會遇到cURL error 60: SSL certificate problem 於是決定以[PHPoAuthLib](https://github.com/Lusitanian/PHPoAuthLib.git)進行開發 所以就寫了[Recca0120 Socialite](https://github.com/recca0120/Socialite) 並使它可以獨立使用 [Demo](https://github.com/recca0120/Socialite/tree/master/demo) 目前只先實作Laravel Socialite原本的功能,之後會視情形再加功能 OAuth1 BitBucket Twitter OAuth2 Facebook GitHub Google Instagram LinkedIn

2015年9月19日 星期六

cURL error 60: SSL certificate problem: unable to get local issuer certificate

![Alt text](http://3.bp.blogspot.com/-0uttRx5fnv4/Vfz6TCVtEhI/AAAAAAAANqc/D6DN3Ys8nGY/s1600/Image%2B2.png) 在使用Guzzle時,遇到cURL error 60: SSL certificate problem: unable to get local issuer certificate 只要下載[ca-bundle.crt](https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt)並放到相對應的路徑 ```php [ // Red Hat, CentOS, Fedora (provided by the ca-certificates package) '/etc/pki/tls/certs/ca-bundle.crt', // Ubuntu, Debian (provided by the ca-certificates package) '/etc/ssl/certs/ca-certificates.crt', // FreeBSD (provided by the ca_root_nss package) '/usr/local/share/certs/ca-root-nss.crt', // OS X provided by homebrew (using the default path) '/usr/local/etc/openssl/cert.pem', // Google app engine '/etc/ca-certificates.crt', // Windows? 'C:\\windows\\system32\\curl-ca-bundle.crt', 'C:\\windows\\curl-ca-bundle.crt', ]; ``` 如果再無法正常運作的話就得去修改php.ini 再加入 ```ini [curl] curl.cainfo=C:\Windows\curl-ca-bundle.crt [openssl] openssl.cafile=C:\Windows\curl-ca-bundle.crt ``` 就可以正常運作了

2015年9月14日 星期一

發撲克牌

在奇摩知識+看到有人發問發撲克牌,依花色及數字大小做排序,所以我就寫了這個程式囉
```php function Poker($member = 4, $POSTCARDS = 52) { /*撲克花色*/ $Poker = [ 'Spades', 'Hearts', 'Diamonds', 'Clubs', ]; /*人頭牌*/ $CARD = [ 11 => 'J', 12 => 'Q', 13 => 'K', ]; /*發牌順序*/ $P = range(0, $POSTCARDS - 1); shuffle($P); /*存放結果陣列*/ $result = []; $total = count($P); for ($i = 0; $i < $total; $i++) { /*發給玩家*/ $t = $i % $member + 1; /*發牌編號 0-51*/ $v = $P[$i]; /*發牌花色 Spades,Hearts,Diamonds,Clubs*/ $c = $Poker[$v % count($Poker)]; /*花色大小 1-13*/ $k = ($v % 13) + 1; $result[$t][$c][$k] = (in_array($k, array_keys($CARD))) ? $CARD[$k] : $k; /*依牌大小排序*/ krsort($result[$t][$c]); /*依花色排序*/ krsort($result[$t]); } return $result; } /*印出結果*/ print_r(Poker(1, 13)); /*如果要發4個人52張牌*/ print_r(Poker(4, 52)); ```

php 下載限速

```php function getlocalfile($filename, $readmod = 1, $range = 0) { if ($fp = @fopen($filename, 'rb')) { @fseek($fp, $range); $download_rate = 10;//限制网速10kb/s while (! feof($fp)) { print fread($fp, round($download_rate * 1024)); flush(); ob_flush(); sleep(1); } } @fclose($fp); @flush(); @ob_flush(); } ```

2015年8月26日 星期三

VirtualBox 5.0.2安裝Mac OS X 10.10 (Yosemite)

新增虛擬主機,並依照圖片中的設定即可正常安裝 1. 版本請選擇 Mac OS X 10.10 Yosemite (64-bit) ![Alt text](http://2.bp.blogspot.com/-IFv5KIalKjY/VduOvZvaRiI/AAAAAAAANpA/lscdHttxjfw/s640/Image%2B1.png) 2. 晶片組 ICH9 指標裝置 USB平板 延伸功能 全選 ![Alt text](http://3.bp.blogspot.com/-lNtA-JXYPKQ/VduOvcot1RI/AAAAAAAANo8/PonTd9hojPk/s1600/Image%2B2.png) 3 啟用 VT-x/AMD-V 啟用Nested Paging ![Alt text](http://4.bp.blogspot.com/-9CAsm5bzvYw/VduOvVbhPCI/AAAAAAAANpE/4dkerBnLzDA/s1600/Image%2B3.png) 4 視訊記憶體調到128M 啟用3D加速 ![Alt text](http://2.bp.blogspot.com/-OYp_OxCRrlk/VduOwFWyOcI/AAAAAAAANpM/Nqaopv8XsQI/s1600/Image%2B4.png) 5 掛載Yosemite原版ISO ![Alt text](http://1.bp.blogspot.com/-QO6Z9N4tm90/VduOwdk1nNI/AAAAAAAANpU/XDj3TvYlI00/s1600/Image%2B5.png) 6. 執行以下指令 ```bash VBoxManage setextradata "虛擬機器名稱" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "MacBookPro11,3" VBoxManage setextradata "虛擬機器名稱" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0" VBoxManage setextradata "虛擬機器名稱" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple" VBoxManage setextradata "虛擬機器名稱" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" VBoxManage setextradata "虛擬機器名稱" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1 VBoxManage setextradata "虛擬機器名稱" "VBoxInternal2/EfiGopMode" 4 ``` 這樣就能在Virtualbox 5.0.2上正常安裝Yosemite

2015年8月14日 星期五

Laravel 5 取得 Artisan::call的執行結果

```php // 輸出結果 class WelcomeController extends controller { public function index() { return response()->stream(function() { Artisan::call('inspire'); echo Artisan::output(); }); } } ```

2015年8月9日 星期日

Laravel 5 資料庫timezone設定

原本在設定database的timezone的設定方式是採取 ```php 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, 'options' => [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET time_zone = "+08:00"' ], ], ``` 後來卻在laravel的原始碼發現 ![Alt text](http://4.bp.blogspot.com/-SLJP_9qgldc/VcdSMcyO8XI/AAAAAAAANoA/8Roi9nPXVfg/s1600/Image%2B6.png) 所以timezone的設定只要這樣寫就可以 ```php 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, 'timezone' => '+08:00', ], ```

2015年8月2日 星期日

找出Windows的序號

重灌或升級windows時有時候會忘記序號 又找不到序號時就很煩好 還好找到一個免費又簡單的找出序號的軟體 ### [Lazesoft Windows Key Finder](http://www.lazesoft.com/lazesoft-windows-key-finder.html) 而且它是Open Source Freeware的軟體 不用擔心會有病毒喔 支援的作業系統 * Windows 2000 SP4 * Windows XP * Windows Vista * Windows 7 * Windows 8 * Windows 8.1 * Windows Server 2003 * Windows Server 2008 * Windows Server 2008 R2 * Windows Server 2012 * Windows Server 2012 R2 支援的OFFICE * Microsoft Office 2000 * Microsoft Office 2003 * Microsoft Office 2007 * Microsoft Office 2010 * Microsoft Office 2013 ![Alt text](http://4.bp.blogspot.com/-JuTNGAZ6EKs/Vb4sYZnDWnI/AAAAAAAANnk/tg2-pPAZENM/s1600/lazesoft-windows-key-finder.jpg)

2015年7月27日 星期一

使用Laravel artisan schedule:run時 exec被禁用時的替代方案

```php namespace App\Console; use Artisan; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ 'App\Console\Commands\Inspire', ]; /** * Define the application's command schedule. * * @param \Illuminate\Console\Scheduling\Schedule $schedule */ protected function schedule(Schedule $schedule) { // 當exec被disabled時只要改成使用Artisan::call('command')即可 $schedule->call(function () { Artisan::call('inspire'); }) ->hourly(); } } ```

遠振主機上利用crontab執行 laravel artisan schedule:run

在專案中有個需求需要在固定時間去抓取固定資料 既然都已經使用laravel所以當然開始使用artisan寫寫console指令 於是很快速的寫完程式,當然第一時間就在自己本機上測試 測試的結果當然是一切都正常 所以很快的就把程式上傳到遠振主機上 並且設定了Cron的排程 ```bash * * * * * php /path/to/artisan schedule:run 1>> /dev/null 2>&1 ``` 設定完後,想說一切都妥當了, 但程式一直出錯 系統就回應 ```ini [ErrorException] Invalid argument supplied foreach() ``` 這要怎麼debug啊 而且明明在自己電腦內測試都能正常執行啊 所以只好開始研究程式碼囉,查到最後原來..... 遠振主機的php預設為 php-cgi 所以無法取得正確的參數 如果要artisan正常執行的話必須使用php-cli 所以在遠振主機上要執行artisan應該要改為 ```bash * * * * * /usr/bin/php-cli /path/to/artisan schedule:run 1>> /dev/null 2>&1 ``` 應該所有的cpanel主機只要是可選php版本的都會遇到這個問題...... php-cli和php-cgi兩個在console上執行的差異 php-cli 的參數會存入 $_SERVER['argv']; php-cgi的參數則會存入 $_GET; 如果要讓php-cgi能正常執行則可以用以下做法 ```php if (empty($_GET) === false) { foreach ($_GET as $key => $value) { $_SERVER['argv'][] = $key; } } ```

2015年4月12日 星期日

sublime 安裝 less

1. 安裝[nodejs](https://nodejs.org/) 2. 開啟cmd,並執行 ```bash npm install -j less ``` 3. sublime安裝 LESS, smart less build 4. 修改smart less build設定檔 ```json { "source_map": false "custom_args": "--clean-css=\"--s1 --advanced --compatibility=ie8\"" } ```

sublime 安裝 coffeescript

1. 安裝[nodejs](https://nodejs.org/) 2. 開啟cmd,並執行 ```bash npm install -j coffee-script ``` 3. sublime安裝 Better CoffeeScript 4. 修改coffeescript設定檔 ```json { "checkSyntaxOnSave": true "lintOnSave": true "lintConfFile": true } ```

sublime syncing

windows內如何同步sublime的設定檔至多台電腦呢? 我們可以利用Dropbox加mklink的方式來做設定喔 請使用系統管理者權限開啟cmd 1.將已設定好的sublime的設定檔移至dropbox內 ```bash mkdir %USERPROFILE%\Dropbox\Sublime cd %APPDATA%\"Sublime Text 3\Packages" copy /Y User\* %USERPROFILE%\Dropbox\Sublime ``` 2.同步所有資料夾 ```bash cd %APPDATA%\"Sublime Text 3\Packages" rmdir /S /Q User mklink /D User %USERPROFILE%\Dropbox\Sublime ```

sublime terminail套件使用git bash

1.安裝 [git](http://git-scm.com/download/win) 2.sublime安裝Terminal 3.將Terminal => Settings - Default的內容複製到Terminal => Settings - User 4.修改 ```json { "terminal": C:\\Program Files\\Git\\git-bash" } ``` ![Alt text](http://1.bp.blogspot.com/-OTlq__5imw4/VSmcvnGcMVI/AAAAAAAANZ4/lWmRDaCk4co/s1600/Image%2B2.png) ![Alt text](http://1.bp.blogspot.com/-QUwHxCmXB5Q/VSmcvU1zWwI/AAAAAAAANZ0/-1DDG3fz1XQ/s1600/Image%2B3.png)

sublime安裝phpcs windows版

1.安裝sublime並安裝好package control 2.安裝phpcs 3.打開command並利用composer安裝 [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) [PHPMD](https://github.com/phpmd/phpmd) ```bash composer global require squizlabs/php_codesniffer fabpot/php-cs-fixer phpmd/phpmd ``` 4.將PHP Code Sniffer => Settings - Default的內容複製到 PHP Code Sniffer => Settings - User 5.修改Settings - User ```json { "phpcs_executable_path": "phpcs.bat", "php_cs_fixer_on_save": true, "php_cs_fixer_executable_path": "php-cs-fixer.bat", "phpcbf_on_save": true, "phpcbf_executable_path": "phpcbf.bat", "phpmd_run": true, "phpmd_executable_path": "phpmd.bat" } ``` 如果進行存檔時還是會提示錯誤訊息修改下列參數即可 ```json { "phpcs_php_prefix_path": "php路徑\\php.exe" } ``` 參考 [wamp安裝](http://phpwrite.blogspot.tw/2015/04/uniform.html) [composer安裝](http://phpwrite.blogspot.tw/2015/04/windowscomposer.html)

如何在windows下安裝composer

[composer](https://getcomposer.org/)是目前最多人使用的php套件管理單, 只要下一個指令, 就可以將所有套件相依性的軟體下載, 並只要require一隻autoload.php即可 不過要安裝composer有些步驟得進行, 說明一下如何安裝composer 1.下載windows版composer[下載](https://getcomposer.org/Composer-Setup.exe) 並安裝(安裝過程中,會要求指定php.exe資料夾) ![Alt text](http://2.bp.blogspot.com/-I2lmx3frsBo/VSl-HVy_XMI/AAAAAAAANZU/6fXNQbx-35c/s1600/Image%2B26.png) 2. 開始右鍵 => 系統 => 進階系統設定 => 環境變數 ![Alt text](http://1.bp.blogspot.com/-tkl3E_1MUec/VSl-EFSQIgI/AAAAAAAANYw/SNSpT9n7Gbk/s1600/Image%2B21.png) 3. 新增變數 變數名稱: PHP_HOME 變數值: PHP路徑(範例為C:\PHP) ![Alt text](http://2.bp.blogspot.com/-BhHP2Y-bOcI/VSl-FL0AORI/AAAAAAAANY4/VSXKh5nCfp0/s1600/Image%2B24.png) 4. 新增變數 變數名稱: COMPOSER_HOME 變數值: C:\ProgramData\ComposerSetup ![Alt text](http://3.bp.blogspot.com/-YSz19_BE54Y/VSl-ufDxGeI/AAAAAAAANZc/5BghqivaO-s/s1600/Image%2B27.png) 5. 修改path 在原本的path後面新增 ;%PHP_HOME%;%COMPOSER_HOME%\bin;%COMPOSER_HOME%\vendor\bin ※由於已經設定%COMPOSER_HOME%所以往後利用 composer global require 套件 都會安裝至%COMPOSER_HOME%\vendor 如果套件內有執行檔則會自動安裝至%COMPOSER_HOME%\vendor\bin 所以%COMPOSER_HOME%\vendor\bin也要加入path變數之中 6. 打開command模式,直接執行composer即可 ![Alt text](http://4.bp.blogspot.com/-pMGSUtfFi0E/VSl_L2L30QI/AAAAAAAANZk/sim4KTe3Fjk/s1600/Image%2B28.png)

uniform server 在windows下體積小快速安裝的wamp server

在Windows裡安裝wamp server 除了常見到的[xampp](https://www.apachefriends.org/zh_tw/index.html)、[wampserver](http://www.wampserver.com/en/)之外 還有這一套『[uniform server](http://www.uniformserver.com/)』 uniform server標榜的是體積小 主程式安裝檔案也才27M 不過相對功能就比較少 安裝程式只包含了apache、php5.4、mysql 其他的phpmyadmin、mariadb等等都可以利用plugin的方式來進行安裝 至於安裝的方法,只要將[檔案](http://sourceforge.net/projects/miniserver/files/latest/download?source=files)下載後,解壓縮到任一資料夾就可以使用了 以下為安裝步驟 1. 下載檔案(只有27M) ![Alt text](http://3.bp.blogspot.com/-1OpE5nbe0Ck/VSlkg8QGYPI/AAAAAAAANWk/rJxUuIhl_3E/s1600/Image%2B2.png) 2. 點擊兩下解壓縮 ![Alt text](http://3.bp.blogspot.com/-gVjjqAGz0ew/VSlk0H47fpI/AAAAAAAANWs/PRIZEwI5yCE/s1600/Image%2B4.png) 3. 進入UniServerZ資料夾 ![Alt text](http://4.bp.blogspot.com/-ULkt4QvuPs0/VSl01m_nBGI/AAAAAAAANYE/O1E0WMWwv0E/s1600/Image%2B6.png) 4. 點擊UniController.exe(用系統管理員身份執行才能設定開機後自動執行wamp) ![Alt text](http://4.bp.blogspot.com/--DmdLAlHbs0/VSl06KhuclI/AAAAAAAANYY/5e9c6N4YD74/s1600/Image%2B8.png) 5. 允許防火牆 ![Alt text](http://2.bp.blogspot.com/-sDRXg7jBMZk/VSl057qZF8I/AAAAAAAANYU/Q5U4Z-NQD8g/s1600/Image%2B9.png) 6. 更改mysql root預設密碼,不更改可直接點選cancel(預設密碼為 root) ![Alt text](http://1.bp.blogspot.com/-4ghg03Fjv4s/VSl0tPRYc_I/AAAAAAAANW8/7yd0XEumQFo/s1600/Image%2B10.png) 7. 啟動apache及mysql ![Alt text](http://3.bp.blogspot.com/-5krQE-FYZqQ/VSl0vwEy0-I/AAAAAAAANXQ/Cr0zYM18-zs/s1600/Image%2B14.png) 8. 設定開機執行apache及mysql ![Alt text](http://3.bp.blogspot.com/-O_Mh5zebdQw/VSl0uV1pF8I/AAAAAAAANXE/ssKUl8_9l5U/s1600/Image%2B15.png) ![Alt text](http://3.bp.blogspot.com/-7Q9jI4UrxZA/VSl0vaCw_4I/AAAAAAAANXM/4Prwe-USgCo/s1600/Image%2B16.png) 9. 這樣就設定完成了 ![Alt text]() 其他比較常用到的apache及php設定 1.設定apache rewrite 2.設定php curl 要更改apache及php的設得先停止apache 設定rewrite的方法 ![Alt text](http://1.bp.blogspot.com/-1LMH9PxQNrw/VSl0yKQ1YZI/AAAAAAAANXc/4HQM073XJpU/s1600/Image%2B17.png) ![Alt text](http://1.bp.blogspot.com/-GF7WQP9_j8c/VSl0y1oj6cI/AAAAAAAANXo/w3Z7lKYxfiw/s1600/Image%2B18.png) 設定php curl ![Alt text](http://2.bp.blogspot.com/-Jnbw7zkMobE/VSl0ywRbxkI/AAAAAAAANXg/AAsOvegL02I/s1600/Image%2B19.png) ![Alt text](http://3.bp.blogspot.com/-q_u8HNyhqMc/VSl00TMYGHI/AAAAAAAANX8/XqYM-jrOEqU/s1600/Image%2B20.png)