Skip to content

Zeroplex 生活隨筆

軟體開發、伺服器和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

標籤: 資訊學習

在 PHP 判斷參數為 anonymous function 的方法

Posted on 2017 年 8 月 1 日2021 年 3 月 12 日 By 日落 在〈在 PHP 判斷參數為 anonymous function 的方法〉中尚無留言

在追各個 framework 的一些元件結構,anonymous function 已經被大量使用在不同的用途上了。

如果 function 要判斷外部傳進來的參數,是否為 anonymous function,有幾個作法。

一個是判斷是否可以被呼叫:

is_callable($param)

另外,由於所有的 anonymous function 其實屬於一個 PHP Closure 類別,所以也可以用下面這個方法做判斷 (且判斷結果還比較準確):

$param instanceof Closure
Tags:PHP, 資訊學習

vim 快速使用 sudo 存檔的語法

Posted on 2017 年 7 月 19 日2021 年 3 月 12 日 By 日落 在〈vim 快速使用 sudo 存檔的語法〉中尚無留言

平常改設定檔通常都是「sudo vim xxx.conf」,不過直接切換成 root 修改檔案其實風險還蠻大的,特別是邊喝酒邊改系統的時候 (?)。

倘若不想使用 sudo vim 來修改系統設定檔時,就 vim xxx.conf 即可。雖然沒有寫入權限,但至少讀取檔案內容是沒問題的。

以一般使用者開啟系統擋時,每次做變更都會收到警告訊息「Warning: Changing a readonly file」,表示 vim 偵測到沒有權限變更檔案內容,避開非預期的異動正是避開誤寫的好方法。那當修改完成後需要寫入時,則可以使用以下指令臨時切換成 root 並寫入檔案:

:w !sudo tee %


說明一下上面那一段到底是什麼意思。

「:w」和大家所知道的寫入檔案是一模一樣的,但若後面加上其他指令,例如「:w ! tee」其實就是把預備寫入的檔案內容 pipe 給後面的指令處理,前面這個寫法就是把檔案內容丟給 console 的 tee 處理,所以可以看到 tee 檔案內容輸出到螢幕上 (stdout)。

vim 中的「%」符號代表的是正在編輯的檔案名稱,可以使用「:!echo %」指令看看會輸出什麼資料。若是「vim xxx.conf」則會印出「xxx.conf」;「vim path/to/xxx.conf」則會印出「path/to/xxx.conf」,應該不難理解。

綜合以上幾個撇步,「:w !sudo tee %」的意思,其實就是讓 vim 不要自己更新檔案,而是將檔案內容拋給以 root 身份執行的 tee,並讓 tee 寫入 vim 目前正在編輯的檔案。tee 寫完檔案以後,vim 會偵測到檔案異動並詢問是否要重新載入 (load) 更新過的檔案內容,重新載入以後就可以繼續下一個批次的修改。

Tags:Linux, Vim, 分享, 資訊學習

Nginx URL rewrite for REST API in subfolder

Posted on 2017 年 7 月 14 日2021 年 3 月 12 日 By 日落 在〈Nginx URL rewrite for REST API in subfolder〉中尚無留言

一般來說,要讓 Nginx 遇到 PHP 程式時,只要按照以下寫法就可以將 request 轉接給 php-fpm 處理:

server {
    location / {
        try_files $uri $uri/index.html =404;
    }

    location ~ .php* {
        root /home/www/data;

        include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }
}

假設 project 在 document root (如上面的就是 /home/www/data),設定方式其實不難,網路到處都可以找的到。像是 Laravel 可以參考 pretty URL 的設定方式,把 index.php 隱藏起來:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

上面這個設定,可以讓 request 從「http://my.site/user/1」,被改寫為「http://my.site/index.php/user/1」,這個時候 index.php 就可以從 $_SERVER 的參數來判斷到底要走哪個 route。

但假設寫的專案沒有一個 domain name、沒辦法做 virtual host,可以讓專案根目錄當作 document root,且新的 PHP framework 都會把 index.php 放在 /public 目錄下來避免安全問題,這樣的 URL rewrite 就會出問題。

例如今天的 request 是「http://my.site/project/user/1」,在經過上面的 route 以後會被轉成「http://my.site/index.php/project/user/1」,而實際上我們需要的是「http://my.site/project/index.php/user/1」才能讓專案正確運作。

這時需要另外建立 route 規則。先把 http://my.site/project 對應到的正確檔案路徑設定好:

location ^~ /project {
    # define script real path
    alias /home/www/data/project/public;

    try_files $uri $uri/ /project/public/index.php$uri;
}

到這邊算是設定完成一半,暫停來看一下目前 routing 的情況。請求「http://my.site/project/user/1」會被轉換為「http://my.site/project/public/index.php/project/user/1」。index.php 後半部的參數差了一點點,把「project/」片段拿掉就完成了。

這時我們再新增一條規則,使用 REGEX 來處理後面這段參數:

location @project-rule {
    # 若 URI 起始為 /project/
    # 把後面的參數抓出來,放在 /project/public/index.php/ 後方 
    rewrite ^/project/(.*)$ /project/public/index.php/$1 last;
}

調整後,完整的 Nginx URL rewrite 規則會長這樣:

location ^~ /project {
    alias /home/www/data/project/public;

    # 一般規則無法正確找到路徑
    # 就使用 @project-rule 規則來做查詢
    try_files $uri $uri/ @project-rule;
}

location @project-rule {
    rewrite ^/project/(.*)$ /project/public/index.php/$1 last;
}

Nginx 的 rewrite rule 實在很難 debug,這段是自己花了數小時嘗試錯誤並觀察 $_SERVER 參數變化才找到規律的,希望多少對大家有一點幫助。

Tags:Nginx, PHP, 分享, 資訊學習

為 Gitlab 加上 CI runner 做自動化測試

Posted on 2017 年 3 月 7 日2021 年 3 月 12 日 By 日落 在〈為 Gitlab 加上 CI runner 做自動化測試〉中尚無留言

gitlab-ci-runner 可以裝在 local 也可以跑在 docker container,我自己是安裝在 docker container:

docker run -d --name gitlab-runner --restart always 
  -v /srv/gitlab-runner/config:/etc/gitlab-runner 
  -v /var/run/docker.sock:/var/run/docker.sock 
  gitlab/gitlab-runner:latest

上面步驟完成以後,可以先進入 Gitlab 的 Admin => Runner,這邊會顯示 runner access token:

在該頁面可以找到 token,如果要讓之前設定的 token 失效,可以先點選「Reset」換一個 acces token:

先把 access token 複製下來,接下來建立一個 runner 並連接到 Gitlab 上:

docker exec -it gitlab-runner gitlab-runner register

設定說明:

  • gitlab-ci coordinator URL:輸入欲使用 runner 的 Gitlab 網址
  • gitlab-ci token:就是你剛剛複製下來的 access token
  • gitlab-ci description:輸入 runner 的名稱,例如 runner-php56 或是 runner-php70。這個名稱會在 Gitlab 上面看到,建議填寫清楚的名稱以供辨識。
  • executor:我這邊要讓 runner 在 docker container 裡面跑,所以選擇「docker」
  • Docker image:在 docker container 執行時,要使用哪個 image 當作 base。我自己懶的自己 built,用的是「edbizarro/gitlab-ci-pipeline-php」
  • gitlab-ci tags for this runner:這邊會請你輸入幾個關鍵字,假設在 project 設定中,出現這幾個關鍵字,則 Gitlab 會自動把符合的 executor on 起來跑。我自己會設定「docker」、「phptest」等等

到這邊若沒看到什麼錯誤,在 Gitlab 的 runner 頁面重新整理後,則頁面最下方可以看到剛剛設定好的 gitlab-ci description (runner name):

這頁有看到的話,可以依樣畫胡驢,在需要使用到的專案 runner 設定頁面,使用這個 runner 來跑測試。


在 Gitlab 上將 runner 設定好,接下來只要在專案上加入「.gitlab.ci.yml」,當 git push 後 Gitlab 便會檔案中的設定自動把 executor on 起來跑,設定方法可以參考 Gitlab 提供的 gitlab-ci.yml 說明。

簡易的 PHP library (不包含任何 framework) project 的 .gitlab-ci.yml 大概長這樣:

image: edbizarro/gitlab-ci-pipeline-php:5.6


syntax-check:
    script:
        - "find . -name '*.php' -print0 | xargs -0 -n1 php -l"
    tags:
        - docker

unit-test:
    script:
        - composer install --prefer-dist --no-ansi --no-interaction --no-progress --no-scripts
        - ./vendor/bin/phpunit -v --coverage-text --colors=never --stderr
    tags:
        - docker

上面可以看到我要求 executor 一定要使用「edbizarro/gitlab-ci-pipeline-php:5.6」這個 image,不過由於 tasks 有特別設定 tags,所以這行也不是必要。

而這邊設定了二個 tasks 要求 executor 協助執行:「syntax-check」和「unit-test」。因此 executor 會先跑 syntax-check,確認沒有錯誤後,再去執行 unit-test。

完成後,只要 Gitlab 收到 commit 且就會依照 .gitlab-ci.yml 的設定下去跑。結果會自動顯示在「Pipeline」的列表當中:

Reference:

  • Install GitLab Runner – GitLab Documentation
  • Configuration of your jobs with .gitlab-ci.yml – GitLab Documentation
  • Build and test PHP applications with Gitlab CI
Tags:PHP, 資訊學習

Laravel 5.3 的 API routing

Posted on 2017 年 3 月 5 日2021 年 3 月 12 日 By 日落 在〈Laravel 5.3 的 API routing〉中尚無留言

弄了很久才搞清楚 5.3 版的 routing 是怎麼搞的,覺得作者把事情弄的更複雜了,也少了一些彈性。

Laravel 5.3 中,routes 已經不是放在 App/Http 底下了,將設定獨立出來放在根目錄:

johnroyer@box:~/devel/laravel53$ tree routes
routes
├── api.php
├── console.php
└── web.php

有個 API 專用 routing 看了當然開心,只是怎麼樣都是不出來 api.php 這邊的設定要怎樣才能起作用。

後來找了很久才發現 Route 功能,已經在 provider 階段把 web / api 的 routing rule 寫死,所以 API 的 routing 有固定的 prefix,在網址是上必須是「http://laravel.root/api」開頭,才會吃到 api.php 的設定。該項 rule 被寫在 RouteServiceProvider 中:

    protected function mapApiRoutes()
    {
        Route::group([
            'middleware' => 'api',
            'namespace' => $this->namespace,
            'prefix' => 'api',
        ], function ($router) {
            require base_path('routes/api.php');
        });
    }

Reference:

  • How to use API Routes in Laravel 5.3 – Stack Overflow
Tags:Laravel, PHP, 資訊學習

文章分頁

上一頁 1 ... 6 7 8 ... 52 下一頁

其他

關於我  (About me)

小額贊助

  文章 RSS Feed

  留言 RSS Feed

Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Ubuntu Unix Vim Web Windows WordPress XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.