[PHP] str_pad 字串補零

str_pad($str,長度,要補的字元,靠左或靠右);
$str = '123';
echo str_pad($str,10,"0",STR_PAD_LEFT);
//輸出:0000000123
echo str_pad($str,10,"0",STR_PAD_RIGHT);
//輸出:1230000000
echo str_pad($str,10,"0",STR_PAD_BOTH);
//輸出:0001230000

[PHP] PHPExcel 檔案匯入

首先我們要先下載PHPExcel
PHPExcel Github https://github.com/PHPOffice/PHPExcel

程式碼:

include_once("/phpexcel/PHPExcel/IOFactory.php");
$file = "upload/test.xlsx";

//$sheetname = 'mysheet'; // 如果要指定工作表
//$objReader->setLoadSheetsOnly($sheetname);

$type = PHPExcel_IOFactory::identify($file); //自動偵測檔案格式
//$type = 'Excel2007'; //也可以手動指定
$objReader = PHPExcel_IOFactory::createReader($type);
$objPHPExcel = $objReader->load($file); //讀取檔案

echo ' 欄數: ' . $getHighestColumn = $objPHPExcel->setActiveSheetIndex()->getHighestColumn(); // 取得寬有幾格
echo ' 行數: ' . $getHighestRow = $objPHPExcel->setActiveSheetIndex()->getHighestRow(); // 共有幾行

// 設定資料區間,設定寬度區間為AC(29格),行數則是取 $getHighestRow,如果不要第一行標題可以把A1改為A2跳過第一行
$range = "A1:AC".$getHighestRow; 

// 不設區間,把所有資料取出
//$sheetData = $objPHPExcel->getActiveSheet()->toArray(null, true, true, true); 

//取出區間資料(陣列)
$sheetData = $objPHPExcel->getActiveSheet()->rangeToArray($range);

print_r($sheetData);

foreach($sheetData AS $k => $v){ // 在此作匯入處理
	// INSERT DB
}

[PHP]取得字串中的數字

大部分的人都會用 preg_replace 正規表達式的方法清除數字以外的字元
不過其實可以用filter_var會比較直覺

$str = 'ABC123DEF';
$number = filter_var($str, FILTER_SANITIZE_NUMBER_INT);
echo $number; // 顯示123的字串

其實 filter_var 可以透過替換掉後方的 “FILTER_SANITIZE_NUMBER_INT” 參數做很多用途,可以參考PHP手冊的參數說明 https://www.php.net/manual/en/filter.filters.php

[PHP]日期時間轉換

取得今天日期

$today = date('Y-m-d');
echo $today.PHP_EOL;

取得今天日期 ( 時分秒 )

$now = date('Y-m-d H:i:s');
echo $now.PHP_EOL;

取得明天日期

$tomorrow = date('Y-m-d',strtotime('+1day'));
echo $tomorrow.PHP_EOL;

加1年1月1日後的日期

$someday= date('Y-m-d',strtotime('+1year +1month +1day'));
echo $someday.PHP_EOL;

也可以加年月日等計算

+1year:年
+1month:月
+1week:週
+1day:天
+1hour:小時
+1minute:分鐘
+1second:秒

特定時間計算

$date = "2019-01-01"; //特定時間
$newdate = date('Y-m-d',strtotime("$date +1month"));
echo $newdate.PHP_EOL;

Y-m-d 參數請參考PHP手冊:https://www.php.net/manual/en/function.date.php

[PHP]時區設定

台灣時區為+8小時,但PHP預設是+0小時
當現在now()應該取得時間為 18:00(GMT+8),但是輸出變成10:00(GMT+10)時
就是時區設定錯誤了,這時要記得修改時區

在PHP的設定檔 ( php.ini ) 找到時區設定

 [Date]
 ; Defines the default timezone used by the date functions
 ; http://php.net/date.timezone
 ;date.timezone = 

更改為(記得移除前面分號)

date.timezone = "Asia/Taipei"

儲存設定後重啟服務就可以了

[PHP]計算2個日期之間有幾天

物件( Object oriented style ):

<?php
$datetime1 = new DateTime('2019-01-01');
$datetime2 = new DateTime('2019-01-31');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
?>

// +30 days

程序式 ( Procedural style ) :

<?php
$datetime1 = date_create('2019-01-01');
$datetime2 = date_create('2019-01-31');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%a days');
?>
// +30 days

$interval->format 輸出格式說明:https://www.php.net/manual/en/dateinterval.format.php

透過迴圈來跑2個日期之間

$fristday = '2019-01-01';
$lastday = '2019-01-31';
$datetime1 = date_create($fristday);
$datetime2 = date_create($lastday);
$interval = date_diff($datetime1, $datetime2);
$godays = $interval->format('%a');
for ($i = 0; $i <= $godays; $i++) {
     $theday = date("Y-m-d",strtotime($fristday." +$i day")); 
     echo $theday.PHP_EOL;
 } 

輸出結果如下:

 2019-01-01
 2019-01-02
 2019-01-03
 2019-01-04
 2019-01-05
 2019-01-06
 2019-01-07
 2019-01-08
 2019-01-09
 2019-01-10
 2019-01-11
 2019-01-12
 2019-01-13
 2019-01-14
 2019-01-15
 2019-01-16
 2019-01-17
 2019-01-18
 2019-01-19
 2019-01-20
 2019-01-21
 2019-01-22
 2019-01-23
 2019-01-24
 2019-01-25
 2019-01-26
 2019-01-27
 2019-01-28
 2019-01-29
 2019-01-30
 2019-01-31

[PHP] require和 include 載入檔案

兩個用法都一樣,就是require('file.php') or include('file.php')

require:

  • 主要用在載入核心程式
  • 載入檔案出錯時程式會執行中斷回報錯誤

include:

  • 建議用在顯示資訊像是 echo 之類用途
  • 出錯只會 Warning 警告,程式還是會繼續執行

require_once & include_once :

  • 系統會檢查是否已載入過,如果已載入就不會再載入
  • 因為多了檢查重複載入,所以跑起來相較於沒 _once 多點效能

所以主要差異就是在中斷這個動作,除非可以接受載入的程式出錯後繼續跑
不然請盡量使用 require 來保持程式的安全

[PHP]Ajax CORS 錯誤

有時在串接Ajax會看到下列錯誤

Access to XMLHttpRequest at 'https://url/test.php' from origin 'http://url' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

錯誤訊息主要是說ajax要連線的網址被瀏覽器的同源政策阻擋(CORS policy)
簡單來說就是ajax連線網址跟現在正在瀏覽網頁的網址不一樣
(就算是http跟https也視同不一樣)
所以ajax連線的程式就要設定Header開放跨網域連線


if($_SERVER['HTTP_ORIGIN'] == "http://URL_A") {
    header('Access-Control-Allow-Origin: http://URL_A');
}else if($_SERVER['HTTP_ORIGIN'] == "https://URL_A") {
    header('Access-Control-Allow-Origin: https://URL_A');
}else if($_SERVER['HTTP_ORIGIN'] == "http://URL_B") {
    header('Access-Control-Allow-Origin: http://URL_B');
}else {
	echo "no auth";
	exit;
}

如果要開放讓所有網域連線的話,設為 * 就可以了

header("Access-Control-Allow-Origin: *");

[PHP]取得用戶IP

主要有2個方式可以取得用戶的IP,分別為 getenv()$_SERVER
不過 getenv() 不支援 IIS 的 ISAPI

getenv():

function get_client_ip() { 
    $client_ip = '';
    if (getenv('HTTP_CLIENT_IP'))
        $client_ip = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $client_ip = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $client_ip = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_X_CLUSTER_CLIENT_IP'))
        $client_ip = getenv('HTTP_X_CLUSTER_CLIENT_IP');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $client_ip = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $client_ip = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $client_ip = getenv('REMOTE_ADDR');
    else if(getenv('HTTP_VIA'))
        $client_ip = getenv('HTTP_VIA');
    else
        $client_ip = '無法取得資訊';
    return $client_ip;
}

$_SERVER:

function get_client_ip() {
    $client_ip = '';
    if (isset($_SERVER['HTTP_CLIENT_IP']))
        $client_ip = $_SERVER['HTTP_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
        $client_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_X_FORWARDED']))
        $client_ip = $_SERVER['HTTP_X_FORWARDED'];
    else if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
        $client_ip = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
        $client_ip = $_SERVER['HTTP_FORWARDED_FOR'];
    else if(isset($_SERVER['HTTP_FORWARDED']))
        $client_ip = $_SERVER['HTTP_FORWARDED'];
    else if(isset($_SERVER['REMOTE_ADDR']))
        $client_ip = $_SERVER['REMOTE_ADDR'];
    else if(isset($_SERVER['HTTP_VIA']))
        $client_ip = $_SERVER['HTTP_VIA'];
    else
        $client_ip = '無法取得資訊';
    return $client_ip;
}

不同的狀況IP會出現在不同的地方
可以從這邊去測試從哪可以抓到IP:http://www.gocar.idv.tw/tools/whatismyip.php