在 Ubuntu 16.04 上安裝舊版的 PHP5.6

[前言]

在這邊只是紀錄要怎麼安裝舊版的PHP而已,可以的話,還是用預設安裝PHP7即可。

[加入外部PPA]


sudo add-apt-repository ppa:ondrej/php

sudo apt-get update

[安裝PHP5.6以及一些phpMyAdmin所必要的extension]


sudo apt-get install php5.6

sudo apt-get install php5.6-mbstring

sudo apt-get install php5.6-mcrypt

sudo apt-get install php5.6-mysql

# 啟動 PHP modules

sudo phpenmod mcrypt
sudo phpenmod mbstring

# 打開編輯器去編輯檔案

# 並把裡面的 mysqli.allow_local_infile = On 前面的註解拿掉

sudo vi /etc/php5/apache2/php.ini

# 重新啟動 Apache2 之後,就結束了。

sudo service apache2 restart

[安裝phpMyAdmin]


sudo apt-get install phpmyadmin

新增 Apache2 VirtualHost 使用子網域以及 Freenom 免費網域的申請

最近正在煩惱著該如何部署 Laravel 到專案的子目錄下,比如說,請求的網址:http://localhost/blog 而不是 http://localhost

使用 .hatcess 之後,還是無法設定成功,讓網址可以導向到請求專案的根目錄名稱一樣也可以成功。

目前也有人有這樣的問題,於是有人在 Laravel 的 Github 的專案上開了這樣的 issue: https://github.com/laravel/framework/pull/3918 問題也是跟我相同,需要請求網址的時候可以多一個專案根目錄名稱。

目前比較好的作法是使用:Apache2 的 VirtualHost 來解決這個問題,透過設定 VirtualHost 可以解決請求網址包含專案名稱的問題。下面的教學為使用 Apache2 VirtualHost 並搭配 Freenom 免費的頂級網域名稱來做到。

作業系統:LUbuntu 16.04 LTS

[Freenom 免費頂級網域申請]

  1. 進入 freenom.com 網站。
  2. 輸入一個沒有人註冊的網域名稱並按下『檢查可用性』,如下圖。
    %e5%bf%ab%e7%85%a710
  3. 註冊或登入一個帳號,並成功拿到網域之後,進到如下的畫面:點選 My Domain 接著選擇 Manage Domain。
    %e5%bf%ab%e7%85%a711
  4. 選擇 tab 名稱:Manage Freenom DNS
    %e5%bf%ab%e7%85%a713
    在『Add record』的部份新增一個 A 紀錄,紀錄 ipv4 位址。Name 空白以及在 Target 的地方,填寫自己的固定 ip 位址所以只適合 VPS 或實體有固定 ip 的主機。(TTL 數值可以用預設就好,不用修改它)
  5. 填寫完成之後,按下 Save Changes 按鈕,等一段時間之後,就會出現『Record added successfully 』就代表成功加入一筆紀錄了。
  6. 增加完 A 紀錄之後,就可以知道使用網域名稱來 request url 而且不需要打 ip 位址了。
  7. 接著再新增 CNAME 紀錄,用來做子網域使用,讓外面連進來的人也可以使用子網域連線(搭配 VirtualHost 使用)。
  8. 新增 CNAME 紀錄範例如下圖:
    %e5%bf%ab%e7%85%a714

[VirtualHost 設定]

  1. 需要先安裝好 Apache2 或是 LAMP server 可以參考之前的文章
  2. 照下面新增一個目錄(以 blog.peter279k.tk)
    sudo mkdir -p /var/www/blog.peter279k.tk/html
    
  3. 設定 permissions 權限,這裡可以將使用者權限設定成:www-data
    sudo chown -R www-data /var/www/blog.peter279k.tk/html
    
  4. 編輯一個測試的設定 HTML 檔。
    vi /var/www/blog.peter279k.tk/html/index.html
    
    <html>
    <head>
    <title>Welcome to Example.com!</title>
    </head>
    <body>
    <h1>Success! The example.com virtual host is working!</h1>
    </body>
    </html>
    
    sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/blog.peter279k.tk.conf
    
    # blog.peter279k.tk.conf
    <VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.
    #ServerName www.example.com
    
    ServerAdmin admin@blog.peter279k.tk
    ServerName blog.peter279k.tk
    ServerAlias www.blog.peter279k.tk
    DocumentRoot /var/www/blog.peter279k.tk/html/blog/public
    
    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    
    <Directory "/var/www/blog.peter279k.tk/html/blog/public">
    AllowOverride All
    </Directory>
    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf
    </VirtualHost>
    
    

    DocumentRoot 和 Directory 需要指定自己的 folder 指定到哪個目錄,網域名稱也需要改成自己改的名稱。

  5. 啟動 site 並重新啟動 Apache2 服務,即完成了。
    sudo a2ensite blog.peter279k.tk.conf
    sudo systemctl restart apache2
    

VirtualHost 設定參考文章:https://www.digitalocean.com/community/tutorials/how-to-set-up-apache-virtual-hosts-on-ubuntu-14-04-lts

從 Curl 到 Guzzle, PHP HTTP client

[前言]

當我們使用 PHP 要爬網頁或做網路機器人的時候,第一個會想到的是:使用 CURL ,他是一個在 Linux 的套件,安裝之後可以使用的指令,因為有繼續發展函式庫的關係,所以陸續針對不同的程式語言開發了 LibCurl,不過 curl 其實在 PHP 不好用,其原因不外乎是使用 curl_init….. 等程序式函式庫而成的。對於一些寫習慣了 OOP 物件導向程式的人來說不習慣。因此在某些原因下,Guzzle, 這個 PHP HTTP client 就產生了。

[安裝]

PHP 最主要的 dependencies package manager 是 Composer 是一個套件管理器,能夠安裝各式套件且不需要匯入。

首先要先安裝好這個。

Guzzle 5.3.0 前置條件:

Requirements
需要 PHP 5.4.0
To use the PHP stream handler, allow_url_fopen must be enabled in your system’s php.ini. allow_url_fopen 設定需要被打開(設定:On)
To use the cURL handler, you must have a recent version of cURL >= 7.16.2 compiled with OpenSSL and zlib. cURL 版本需要 7.16.2 以上且 有把 OpenSSL and zlib 編譯進去

Step1:

下載 composer.phar,利用下面指令就會自動安裝最新版的 composer.phar

curl -sS https://getcomposer.org/installer | php

Step2:

當然也可以選擇手動安裝,進入下載頁面,拉到最下面有 Manual Download 字眼,為手動安裝。

Step3:編寫 composer.json 並執行:php composer.phar install 如果之前已經有使用 composer.json 則輸入:php composer.phar update

或直接在專案目錄下值接輸入:php composer.phar require guzzlehttp/guzzle

{
    "require": {
       "guzzlehttp/guzzle":"5.*.*"
    }
} 

我們安裝第五版,第五版與第六版是目前官方所支援的,寫法有異,這篇先以第五版做為範例。

Step3:接下來的範例,我用幾個常用的服務做為範例,分別是下再一個網頁, Google reCaptcha API驗證,和寄信服務MailGun (cURL),以及上傳圖床服務 imgur (用 cURL)等這四個範例。

[範例 1:Mailgun]

Mailgun 是一個發送信件的服務,相較自己架的Mail server 發信,信件不會被丟到垃圾信件中。也省去一些繁複的設定。

下面是一個使用 libcURL 的 PHP 程式碼:


function send_simple_message() {
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
     curl_setopt($ch, CURLOPT_USERPWD, 'api:key-your-key');
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
     curl_setopt($ch, CURLOPT_URL,
              'https://api.mailgun.net/v3/your-domain.mailgun.org/messages');
     curl_setopt($ch, CURLOPT_POSTFIELDS,
            array('from' => 'peter <peter279k@gmail.com>',
                  'to' => 'peter <peter279k@gmail.com>',
                  'subject' => 'Hello',
                  'text' => 'Hello World'));
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

如果用 Guzzle 寫的:其實不會差很多,主要是 Guzzle 是以 libcURL 為基礎的,用 OOP 物件導向的程設重新設計過,所以使用起來會比較直覺。

需注意的是,HTTP-BASIC 用法不太一樣,冒號隔開分別是,使用者名稱與密碼。


require "vendor/autoload.php";

$client = new GuzzleHttp\Client([
'defaults' => [
      'auth' => ['api', 'key-your-api-key'],
    ]
]);

$client -> setDefaultOption('verify', false);
$res = $client->post('https://api.mailgun.net/v3/your-domain.mailgun.org/messages', [
'body'=>[
    'from' => 'peter <peter279k@gmail.com>',
    'to' => 'peter <peter279k@gmail.com>',
    'subject' => 'Hello',
    'text' => 'Hello World'
  ]
]);
var_dump($res->json());

[範例 2:Imgur]

Imgur 是一個好用的圖床服務,通常會拿來上傳圖片,當然也有提供各式的 API 可供授權 authLoginURL 與上傳圖片。

下面是一個使用 libcURL 的 PHP 程式碼:


$client_id = "your-imgur-client-id";
$image = file_get_contents("/path/to/image.png");

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($image)));

$reply = curl_exec($ch);
curl_close($ch);

$reply = json_decode($reply, true);

var_dump($reply);

用 Guzzle HTTP Client 寫的:


$imageFile = file_get_contents("../imgur_result.png");

$client = new GuzzleHttp\Client([
     'defaults' => [
         'headers' => ['Authorization' => 'Client-ID 3aa5c24753e1656'],
     ]
]);

$res = $client->post('https://api.imgur.com/3/image.json', [
      'body'=>[
         'image' => base64_encode($imageFile)
      ]
]);

var_dump($res->json());

[範例 3: Google reCaptcha API]

[未完,待續……]

[Ref. 參考資料]

Mailgun心得筆記

Guzzle 5.3 docs

Mailgun 介紹

[後記]

下兩篇將會單獨介紹寄信服務與 Imgur 的圖床服務