PHP Tips
Magic constants
似乎有許多"魔術"設計在 PHP 裡
__FILE__
: /path/to/file
__DIR__
: /path/to
__FUNCTION__
: 一般 namespace\function_name;類別中 function_name
__CLASS__
: 帶 NAMESPACE;namespace\class_name
__METHOD__
: 帶 NAMESPACE;namespace\class_name::function_name
__LINE__
: (int) 55
__NAMESPACE__
: namespace
回傳 data 時記得送 header
// JSON
header('Content-Type: application/json; charset=utf-8');
// XML
header('Content-type: text/xml');
難怪我之前寫 ajax 需要手動 parseJSON ...
PHP Timezone List
print_r(DateTimeZone::listIdentifiers(DateTimeZone::ALL));
$timezones = array(
'Pacific/Midway' => "(GMT-11:00) Midway Island",
'US/Samoa' => "(GMT-11:00) Samoa",
'US/Hawaii' => "(GMT-10:00) Hawaii",
'US/Alaska' => "(GMT-09:00) Alaska",
'US/Pacific' => "(GMT-08:00) Pacific Time (US & Canada)",
'America/Tijuana' => "(GMT-08:00) Tijuana",
'US/Arizona' => "(GMT-07:00) Arizona",
'US/Mountain' => "(GMT-07:00) Mountain Time (US & Canada)",
'America/Chihuahua' => "(GMT-07:00) Chihuahua",
'America/Mazatlan' => "(GMT-07:00) Mazatlan",
'America/Mexico_City' => "(GMT-06:00) Mexico City",
'America/Monterrey' => "(GMT-06:00) Monterrey",
'Canada/Saskatchewan' => "(GMT-06:00) Saskatchewan",
'US/Central' => "(GMT-06:00) Central Time (US & Canada)",
'US/Eastern' => "(GMT-05:00) Eastern Time (US & Canada)",
'US/East-Indiana' => "(GMT-05:00) Indiana (East)",
'America/Bogota' => "(GMT-05:00) Bogota",
'America/Lima' => "(GMT-05:00) Lima",
'America/Caracas' => "(GMT-04:30) Caracas",
'Canada/Atlantic' => "(GMT-04:00) Atlantic Time (Canada)",
'America/La_Paz' => "(GMT-04:00) La Paz",
'America/Santiago' => "(GMT-04:00) Santiago",
'Canada/Newfoundland' => "(GMT-03:30) Newfoundland",
'America/Buenos_Aires' => "(GMT-03:00) Buenos Aires",
'Greenland' => "(GMT-03:00) Greenland",
'Atlantic/Stanley' => "(GMT-02:00) Stanley",
'Atlantic/Azores' => "(GMT-01:00) Azores",
'Atlantic/Cape_Verde' => "(GMT-01:00) Cape Verde Is.",
'Africa/Casablanca' => "(GMT) Casablanca",
'Europe/Dublin' => "(GMT) Dublin",
'Europe/Lisbon' => "(GMT) Lisbon",
'Europe/London' => "(GMT) London",
'Africa/Monrovia' => "(GMT) Monrovia",
'Europe/Amsterdam' => "(GMT+01:00) Amsterdam",
'Europe/Belgrade' => "(GMT+01:00) Belgrade",
'Europe/Berlin' => "(GMT+01:00) Berlin",
'Europe/Bratislava' => "(GMT+01:00) Bratislava",
'Europe/Brussels' => "(GMT+01:00) Brussels",
'Europe/Budapest' => "(GMT+01:00) Budapest",
'Europe/Copenhagen' => "(GMT+01:00) Copenhagen",
'Europe/Ljubljana' => "(GMT+01:00) Ljubljana",
'Europe/Madrid' => "(GMT+01:00) Madrid",
'Europe/Paris' => "(GMT+01:00) Paris",
'Europe/Prague' => "(GMT+01:00) Prague",
'Europe/Rome' => "(GMT+01:00) Rome",
'Europe/Sarajevo' => "(GMT+01:00) Sarajevo",
'Europe/Skopje' => "(GMT+01:00) Skopje",
'Europe/Stockholm' => "(GMT+01:00) Stockholm",
'Europe/Vienna' => "(GMT+01:00) Vienna",
'Europe/Warsaw' => "(GMT+01:00) Warsaw",
'Europe/Zagreb' => "(GMT+01:00) Zagreb",
'Europe/Athens' => "(GMT+02:00) Athens",
'Europe/Bucharest' => "(GMT+02:00) Bucharest",
'Africa/Cairo' => "(GMT+02:00) Cairo",
'Africa/Harare' => "(GMT+02:00) Harare",
'Europe/Helsinki' => "(GMT+02:00) Helsinki",
'Europe/Istanbul' => "(GMT+02:00) Istanbul",
'Asia/Jerusalem' => "(GMT+02:00) Jerusalem",
'Europe/Kiev' => "(GMT+02:00) Kyiv",
'Europe/Minsk' => "(GMT+02:00) Minsk",
'Europe/Riga' => "(GMT+02:00) Riga",
'Europe/Sofia' => "(GMT+02:00) Sofia",
'Europe/Tallinn' => "(GMT+02:00) Tallinn",
'Europe/Vilnius' => "(GMT+02:00) Vilnius",
'Asia/Baghdad' => "(GMT+03:00) Baghdad",
'Asia/Kuwait' => "(GMT+03:00) Kuwait",
'Africa/Nairobi' => "(GMT+03:00) Nairobi",
'Asia/Riyadh' => "(GMT+03:00) Riyadh",
'Europe/Moscow' => "(GMT+03:00) Moscow",
'Asia/Tehran' => "(GMT+03:30) Tehran",
'Asia/Baku' => "(GMT+04:00) Baku",
'Europe/Volgograd' => "(GMT+04:00) Volgograd",
'Asia/Muscat' => "(GMT+04:00) Muscat",
'Asia/Tbilisi' => "(GMT+04:00) Tbilisi",
'Asia/Yerevan' => "(GMT+04:00) Yerevan",
'Asia/Kabul' => "(GMT+04:30) Kabul",
'Asia/Karachi' => "(GMT+05:00) Karachi",
'Asia/Tashkent' => "(GMT+05:00) Tashkent",
'Asia/Kolkata' => "(GMT+05:30) Kolkata",
'Asia/Kathmandu' => "(GMT+05:45) Kathmandu",
'Asia/Yekaterinburg' => "(GMT+06:00) Ekaterinburg",
'Asia/Almaty' => "(GMT+06:00) Almaty",
'Asia/Dhaka' => "(GMT+06:00) Dhaka",
'Asia/Novosibirsk' => "(GMT+07:00) Novosibirsk",
'Asia/Bangkok' => "(GMT+07:00) Bangkok",
'Asia/Jakarta' => "(GMT+07:00) Jakarta",
'Asia/Krasnoyarsk' => "(GMT+08:00) Krasnoyarsk",
'Asia/Chongqing' => "(GMT+08:00) Chongqing",
'Asia/Hong_Kong' => "(GMT+08:00) Hong Kong",
'Asia/Kuala_Lumpur' => "(GMT+08:00) Kuala Lumpur",
'Australia/Perth' => "(GMT+08:00) Perth",
'Asia/Singapore' => "(GMT+08:00) Singapore",
'Asia/Taipei' => "(GMT+08:00) Taipei",
'Asia/Ulaanbaatar' => "(GMT+08:00) Ulaan Bataar",
'Asia/Urumqi' => "(GMT+08:00) Urumqi",
'Asia/Irkutsk' => "(GMT+09:00) Irkutsk",
'Asia/Seoul' => "(GMT+09:00) Seoul",
'Asia/Tokyo' => "(GMT+09:00) Tokyo",
'Australia/Adelaide' => "(GMT+09:30) Adelaide",
'Australia/Darwin' => "(GMT+09:30) Darwin",
'Asia/Yakutsk' => "(GMT+10:00) Yakutsk",
'Australia/Brisbane' => "(GMT+10:00) Brisbane",
'Australia/Canberra' => "(GMT+10:00) Canberra",
'Pacific/Guam' => "(GMT+10:00) Guam",
'Australia/Hobart' => "(GMT+10:00) Hobart",
'Australia/Melbourne' => "(GMT+10:00) Melbourne",
'Pacific/Port_Moresby' => "(GMT+10:00) Port Moresby",
'Australia/Sydney' => "(GMT+10:00) Sydney",
'Asia/Vladivostok' => "(GMT+11:00) Vladivostok",
'Asia/Magadan' => "(GMT+12:00) Magadan",
'Pacific/Auckland' => "(GMT+12:00) Auckland",
'Pacific/Fiji' => "(GMT+12:00) Fiji",
);
判斷是否為 CLI 模式
// method 1
if (PHP_SAPI != "cli") die('not cli mode');
// method 2
if ( isset($_SERVER['argc']) && $_SERVER['argc']>=1 ) die('is cli mode');
PHP Closure
PHP external call
PHP 執行系統外部命令: system() exec() passthru() 與 反撇號法
PHP micro timestamp to date
毫秒部分要獨立處理
// Target: Y-m-d h:i:s.u
$microtime = 1512464879000;
// sol 1
$time_converter = function($microtime) {
return date('Y-m-d h:i:s.u', substr($microtime, 0, -3)) . '.' . substr($microtime, -3);
}
// sol 2
$time_converter = function($microtime, $tz = true) {
$datetime = \DateTime::createFromFormat('U.u', number_format($microtime*0.001, 6, '.', ''))
;f if($tz) $datetime->setTimezone(new \DateTimeZone('Asia/Taipei'));
return $datetime;
};
PHP self 與 static
Class A {
public static function get_self() {
return new self();
}
public static function get_static() {
return new static();
}
}
class B extends A {}
echo get_class(B::get_self()); // return A
echo get_class(B::get_static()); // return B
echo get_class(A::get_static()); // return A
推算離最近時間最近的開獎日
<?php
date_default_timezone_set("Asia/Taipei");
$time = time();
// echo $time, "\n", date('D', $time),"\n";
// echo date('r', 0), "\n";
// 時間戳 0 為星期四
$period = [1 => 'Fri', 2 => 'Sat', 3 => 'Sun', 4 => 'Mon', 5 => 'Tue', 6 => 'Wed', 7 => 'Thu'];
$days = ['Tue', 'Thu', 'Sat'];
function getClosetTimestamp ($days, $timestamp) {
$day = date('D', $timestamp);
if(in_array($day, $days)) $closetTimestamp = $timestamp;
else {
echo $timestamp = strtotime(date('Y-m-d', $timestamp)) + 86400, "\n";
$closetTimestamp = getClosetTimestamp($days, $timestamp);
}
return $closetTimestamp;
}
// 測試推算開獎日
foreach (array_keys($period) as $multiply) {
$timestamp = $time + 86400 * $multiply;
echo "乘數為 $multiply, 投注時間為 " . date('Y-m-d, D', $timestamp), "\n";
$resultTime = getClosetTimestamp($days, $timestamp);
echo "開獎日為 " . date('Y-m-d 21:35:00, D', $resultTime), "\n";
}
浮點數比對陷阱
不只 PHP,其他語言的浮點數比對也要注意;原因是精確度的關係;小數存放是差分器的方法
整理一下解法
- bcadd() 與 bcsub()
- 根據用途自己 round(), ceil(), floor(), intval() and so on
刪除多餘的字元
- 多餘的 slashes in path/url
preg_replace('#/+#','/',$str);