2019年8月8日 星期四

switch 中的 continue (C、PHP)

[在 switch 中使用 continue]
C:
在 C 的 switch 中使用 continue,若不是在迴圈中,出現錯誤
#include 
#include 

int main(int argc, char** argv) {
    int c = 10;
    switch (c) {
        case 7:
            continue;//error:continue statement not within a loop
    }
    return (EXIT_SUCCESS);
}

PHP:
在 PHP 的 switch 中使用 continue,沒傳遞參數時,跟使用 break 意思一樣
 「In PHP the switch statement is considered a looping structure for the purposes of continue. continue behaves like break (when no arguments are passed). If a switch is inside a loop, continue 2 will continue with the next iteration of the outer loop.
參考:https://www.php.net/manual/en/control-structures.continue.php
$c=7;
switch ($c) {
  case 7:
      var_dump("continue test");
    continue;
  default:
      var_dump($c);
    break;
}
//輸出 string(13) "continue test"




[在迴圈中的 switch 中使用 continue]
C:
在 C ,迴圈(例如while)中的 switch 使用 continue,效用會針對迴圈(例如while)
#include 
#include 

int main(int argc, char** argv) {
    int c = 10;
    while (c > 6) {
        c--;
        switch (c) {
            case 7:
                continue;
        }
        printf("%d\n", c);

    }
    return (EXIT_SUCCESS);
}
/*
輸出
9
8
6
*/

PHP:(情況一)
在 PHP,迴圈(例如while)中的 switch 使用 continue,沒傳遞參數時,跟使用 break 意思一樣
$c=10;
while ($c>6) {
   $c--;
   switch ($c) {
      case 7:
        var_dump("continue test");
        continue;
   }
   var_dump($c);
}
/*
輸出
int(9)
int(8)
string(13) "continue test"
int(7)
int(6)
*/
註:在 PHP 7.3 以上,迴圈內的 switch 使用「continue」、「continue 1」,會出現
Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"?
,因為「continue」、「continue 1」其實就等於「break」,開發者寫「continue」不寫「break」,很可能是為了作用到外層的迴圈,所以出現此Warning,提醒開發者。

PHP:(情況2)
在 PHP,迴圈(例如while)中的 switch 使用 continue,若要對外層的迴圈作用,須使用「continue 數字」。
例如「continue 2」,
第1次continue作用在內層的switch,
第2次continue作用在外層的迴圈(例如while)。
$c=10;
while ($c>6) {
   $c--;
   switch ($c) {
      case 7:
        var_dump("continue test");
        continue 2;
   }
   var_dump($c);
}
/*
輸出
int(9)
int(8)
string(13) "continue test"
int(6)
*/


2019年4月9日 星期二

Nginx HTTP 自動轉址到 HTTPS

[情況1]:HTTP 和 HTTPS 使用不同 PORT
例如,分別使用預設的 80、443 PORT
http://example.com 的網址要強制轉到 https://example.com
可直接在 HTTP 的設定中,return 301 轉址到 HTTPS
server {
    listen 80;
    
    server_name example.com;

    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    server_name example.com;
}



[情況2]:將原本 HTTP 使用的 PORT,直接改給 HTTPS 使用。
修改前後 HTTP、HTTPS 使用相同的 PORT,例如都使用 8080 PORT
處理方式:若在 HTTPS 的 PORT 上,使用 HTTP 訪問,會出現 error_page 497 的錯誤。當發生此錯誤時,將頁面轉址到 HTTPS 的網址。
server {
    listen 8080 ssl;
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    server_name example.com;

    #error_page 497 301 =307 https://$host:$server_port$request_uri;
    error_page 497 https://$host:$server_port$request_uri;
}



參考:
Handling http and https requests using a single port with nginx - Server Fault
http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
ngxin做http强制跳转https,接口的POST请求变成了GET
nginx error_page - IT閱讀
nginx不得不说的参数之 为什么nginx error_page遇到后端错误时不跳转?-运维者说:从菜鸟到老鸟-51CTO博客


2019年2月11日 星期一

Node.js 執行 Linux 指令

使用 Node.js 建立網頁,網頁可透過 Node.js 執行 Linux 上的指令。
網頁的部分,使用 Express 網頁框架。使用 9000 PORT


建立 Node.js 專案,防火牆開放網頁預計使用的 9000 PORT
npm init
npm install express --save
#防火牆
firewall-cmd --state
firewall-cmd --list-all --zone=public
firewall-cmd --permanent --zone=public --add-port=9000/tcp
firewall-cmd --reload


Node.js 程式內容
let express = require('express');
let app = express();
let router = express.Router();
let exec = require('child_process').exec;
let port = 9000;
//app.use(express.static(__dirname + '/public'));
//app.use('/img', express.static(__dirname + '/public/img'));

let header = '<!DOCTYPE html><html><head><title>ctrl PHP</title>'
        + '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
        + '<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">'
        + '</head><body><pre>';
let footer = "</pre></body></html>";

router.get('/', function (req, res, next) {
    //預設頁面
    console.log('index');
    res.sendfile('index.html', {root: __dirname + "/public"});
});
router.get('/ls', function (req, res, next) {
    //執行 ls -al 指令
    exec('ls -al', function (err, stdout, stderr) {
        console.log('ls');
        res.send(header + stdout + footer);
    });
});

app.use('/', router);
app.listen(port);



參考:
express nodejs execute ubuntu shell terminal command, ls, cat
Express.js 4.0 的路由(Router)功能用法教學 - G. T. Wang
node.js - simplest way to have Express serve a default page? - Stack Overflow
在 Express 中提供靜態檔案


2018年10月24日 星期三

找回 Nodepad++ 當掉崩潰不見的檔案內容

Nodepad++ 版本:7.5.7 (32bit)

情況:使用 Nodepad++ 編輯文字檔儲存時,突然當掉崩潰,重開 Nodepad++ 後,原來編輯的檔案內容全被清空不見。

解決方式:
查看「設定」->「使用者自訂」裡的「備份」,查看「檔案群組快照和定期備份」中的「備份路徑」位置。
到「備份路徑」位置,幸運的話,可找到「檔案名稱@時間」的備份檔案。
將檔名後面的「@時間」去掉,就是一般的文字檔。這可以找回之前某一時間點的備份內容,雖然還是會遺失後來編輯的內容,但至少可救回之前的內容。



另外自訂備份:
如果對上面的自動備份設定不放心,該設定下面還有一個「備份」的設定。
我測試的效果是,

「簡易備份」:每次儲存時將未編輯前的檔案,複製一份「原檔名」的檔案到「自訂備份資料夾」,該資料夾只會有一份該檔名的備份檔。

「詳細備份」:每次儲存時將未編輯前的檔案,複製一份「原檔名@時間」到「自訂備份資料夾」,該資料夾會有多份該檔名的不同時間點的備份檔。

最後我選用「詳細備份」,因為可避免檔案路徑不同,但檔名相同的檔案,備份檔案一定會互相覆蓋的情況。




參考:
Notepad ++ Crashed? Lost Notepad ++ Files? Restore Right Now! – EaseUS
file - Lost code lines when Notepad++ crashed - Stack Overflow


2018年9月6日 星期四

PHP strtotime 月份加減

PHP 的 strtotime 可以進行月份的加減。
但 PHP 進行時,會保留原來的「日」,再判斷是否需進行時間的偏移,所以可能導致最終的日期跟預想的不一樣。
例如:
$cur_date = "2016-03-31";
var_dump(date("Y-m-d", strtotime("-1 month", strtotime($cur_date))));//2016-03-02
var_dump(date("Y-m-d", strtotime("+1 month", strtotime($cur_date))));//2016-05-01
2016-03-31 減一個月變成 2016-02-31,但2016年2月只到29號,所以 2016-02-31 => 2016-03-02
2016-03-31 加一個月變成 2016-04-31,但4月只到30號,所以 2016-04-31 => 2016-05-01

這結果,可能跟預想的不太一樣。
但如果只是要取月份加減後的月初、月底,或只著重在結果的月分準確即可,
那可使用「first day of」(取月初)、「last day of」(取月底)來處理。
加減過程中,沒了原本的「日」,也就沒最後因為「日」而導致月份的偏移了。
$cur_date = "2016-03-31";
var_dump(date("Y-m-d", strtotime("first day of -1 month", strtotime($cur_date))));//2016-02-01
var_dump(date("Y-m-d", strtotime("last day of -1 month", strtotime($cur_date))));//2016-02-29
var_dump(date("Y-m-d", strtotime("first day of +1 month", strtotime($cur_date))));//2016-04-01
var_dump(date("Y-m-d", strtotime("last day of +1 month", strtotime($cur_date))));//2016-04-30


最後測試一下跨年是否有影響。
結果:跨年度的話,似乎「年」能先準確的計算出來。至於最後會不會自動偏移,一樣是看該「年-月」是否有該日期決定。
$cur_date = "2017-03-29";
var_dump(date("Y-m-d", strtotime("-13 month", strtotime($cur_date))));//2017-02-29

$cur_date = "2017-03-30";
var_dump(date("Y-m-d", strtotime("-13 month", strtotime($cur_date))));//2016-03-01
var_dump(date("Y-m-d", strtotime("first day of -13 month", strtotime($cur_date))));//2016-02-01
var_dump(date("Y-m-d", strtotime("last day of -13 month", strtotime($cur_date))));//2016-02-29


參考:
令人困惑的strtotime | 风雪之隅