Skip to content

Zeroplex 生活隨筆

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

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

標籤: PHP

PHP array key 的資料型態

Posted on 2016 年 5 月 22 日2021 年 3 月 12 日 By 日落 在〈PHP array key 的資料型態〉中尚無留言

之前因為 array_merge() 花了很久的時間 debug,這次發現其實不只 array_merge() 會需要注意資料型態的問題,其他 statement 也要注意。

這次遇到是因為使用 time 當作 array 的 key 時發現的:

$timeTable = [];
$timeTable['0800'] = '早上';
$timeTable['1200'] = '中午';
$timeTable['2000'] = '晚上';

取直時發現資料型態和 assign 時不一樣,可以被轉成數字的全部變成數字了:

array(3) {
  ["0800"]=>
  string(6) "早上"
  [1200]=>
  string(6) "中午"
  [2000]=>
  string(6) "晚上"
}

原因是 PHP array 的預設行為,是會自動對 key 作 type casting。可被判斷成數值的 (is_numeric()) 都會自動被轉為 int。所以撰寫時要注意,如果 array 的 key 若需要避免被 casting 時,必須手動加上一些字元讓 is_numeric() 無法將其判斷為數字。

以上面的例子,可以將時間加上「:」

  • 08:00
  • 12:00
  • 20:00

Ref:

  • PHP: Arrays – Example #2 Type Casting and Overwriting example
Tags:PHP

PHP namespace

Posted on 2016 年 5 月 15 日2021 年 3 月 12 日 By 日落 在〈PHP namespace〉中尚無留言

PHP 可以自行定義程式中定義的方法、類別所屬的 namespace,但是若在 namespace 定義之前就先就先寫了其他 statement則會出現錯誤訊息。例如以下的程式:

<?php

$a = 1;

namespace Zeroplex;

執行後變會出現錯誤訊息:

Fatal error: Namespace declaration statement has to be the very first statement in the script ....

主要是因為變數、函式、類別都可以有自己所屬的 namespace,若沒有事先定義該程式所屬的 namespace,PHP 則會造成混淆而發生錯誤。

總之,namespace 的定義,直接方在 open tag 之後的第一行,避免這類問題發生。

Tags:PHP

特定情況下 PHP 可以比 awk 還要快

Posted on 2015 年 11 月 10 日2021 年 3 月 12 日 By 日落 在〈特定情況下 PHP 可以比 awk 還要快〉中尚無留言

因為工作上的需要,會需要將 HTTP log 抓出來做統計,所以會遇到類似下方的 RESTful path:

GET /user/123/bio HTTP/1.1 ...
GET /user/456/bio HTTP/1.1 ...

如果取完整的 path 則無法辨別後端到底是使用哪一個 API,所以使用 awk 的 regex 辨識後 mapping 到 API 名稱上。寫完以後的 awk script 大約有 300 行左右,一份 log 大概要花 2 分鐘左右。

後來經高人指點,PHP 的 native library 好歹也是 C++ 寫的,理論上不會太慢,於是用 PHP 的 preg_match() 將相同的邏輯寫了一次。同一份 log 使用 PHP 來 parse 大約只需要 1 分 32秒。

另外 PHP 預設會載入已安裝的 extensions (mysql, mcrypt …),既然只用到 native library 的話,其實這些也可以去掉不要用。改為「php -n」不載入任何 extension 再執行時,速度又快了一些,只要約 1 分鐘。

PHP 其實還有一些可以繼續調整的東西,像是把資料放在陣列裡面做搜尋時,如果把資料存成 array index 並使用 array_key_exists() 方式去判斷,會比 in_array() 還要更快 [Ref]。

Tags:Bash, PHP

PHP array_merge() 在資料型別上行為的差異

Posted on 2014 年 11 月 25 日2021 年 3 月 12 日 By 日落 在〈PHP array_merge() 在資料型別上行為的差異〉中有 2 則留言

array_merge() 可合併多個陣列,遇到相同的陣列索引,將由後方陣列的值取代前一個值。

如:

$d = array(
  'a' => 111,
  'b' => 222,
);
 
$e = array(
  'a' => 123,
  'c' => 333,
);
var_dump(array_merge($d, $e));

執行結果為:

array(3) {
  ["a"]=>
  int(123)
  ["b"]=>
  int(222)
  ["c"]=>
  int(333)
}

此特性常被用來做設定選項合併,如:

function__construct(array $config){
  $defaultsStyle = array(
    'display' => true,
    'color' => 'red',
    'size' => '14px',
  );

  $settings = array_merge($defaultStyle, $config);

  // initialize by $settings
}

上面的寫法可以讓預設的三項索引「display」、「color」、「size」一定存在,不需特別在做 array_key_exists() 檢查,且外部傳入的數值,會將內定的預設值覆蓋掉。

不過只有字串型態的陣列索引,經過 array_merge() 以後可以保留原有的索引名稱,若為數字型態的陣列索引,array_merge() 會將原有索引打掉重新排列。

如:

$d = array(
  0 => 111,
  1 => 222,
);
 
$e = array(
  9 => 123,
  7 => 333,
);
var_dump(array_merge($d, $e));

執行的結果會是:

array(4) {
  [0]=>
  int(111)
  [1]=>
  int(222)
  [2]=>
  int(123)
  [3]=>
  int(333)
}

另外 array_merge() 有個很奇怪的行為,假設陣列的索引是「類似數字」的字串 (不曉得判斷規則為何),像是 “100”、”200″,經過 array_merge() 時會被當成數字型索引處理。

如:

$d = array(
  '100' => 111,
  '200' => 222,
);
 
$e = array(
  '100' => 100,
  '300' => 333,
);
var_dump(array_merge($d, $e));

執行後為:

array(4) {
  [0] =>
  int(111)
  [1] =>
  int(222)
  [2] =>
  int(100)
  [3] =>
  int(333)
}

若索引名稱為 “001”、”002″,經過 array_merge() 才會被當成字串,不會有上述情況發生。

要避免索引被吃掉,可以改用 array unioin operator:

$d = array(
  '100' => 111,
  '200' => 222,
);
 
$e = array(
  '100' => 100,
  '300' => 333,
);
var_dump($d + $e));

陣列索引會被保留下來:

array(3) {
  [100] =>
  int(111)
  [200] =>
  int(222)
  [300] =>
  int(333)
}

不過要注意的是,array union operator 遇到相同索引時,陣列值並不會被後方的陣列取代 ($merged[‘100’] 會是 111 而非 100),所以使用時要注意順序問題。

總之,’100’、’200′ 被 array_merge() 當成數字讓我極度不爽。

Tags:PHP

使用 ini_set() 設定 Xdebug function calls trace

Posted on 2014 年 1 月 14 日2021 年 3 月 12 日 By 日落 在〈使用 ini_set() 設定 Xdebug function calls trace〉中尚無留言

Xdebug 是一個在 PHP 上很好用的除錯工具,特別是 function calls tracing,可以很完整的列出執行流程。Xdebug 的介紹可以參考 Crboy 的文章:

  • Xdebug 基礎安裝與使用
  • Xdebug 遠端除錯 (Remote Debugging)

要讓 Xdebug 在 PHP 開始執行時自動 trace function calls,只需要在 ini file 加上 xdebug.auto_trace = On 即可。若沒有系統權限,仍可以使用 PHP 的 ini_set() 設定 Xdebug 各項參數:

<?php

ini_set('xdebug.trace_output_dir', '/tmp/xdebug');
xdebug_start_trace();  // start tracing

// beginning of program

要注意的是,tracing 的設定會在 PHP 開始執行前便載入,所以使用 ini_set() 設定 xdebug.auto_trace 是不會起作用的:

<php

ini_set('xdebug.auto_trace', 'On');  // 沒有作用
ini_set('xdebug.trace_output_dir', '/tmp/xdebug');

// beginning of program

ps. 若 auto trace 已啟動,要記得定期清理 log,免得硬碟被吃光導致機器故障。

Tags:PHP

文章分頁

上一頁 1 ... 17 18 19 ... 26 下一頁

其他

關於我  (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 國際 授權條款授權.