RWD風行,所以網站的前端要考慮的層面就多了很多,前端目前缺乏所以得自己來,浮動式固定選單挺常用到,備忘囉!!
CSS
<style>
.navFixed {
z-index: 10;
position: fixed;
top: 0;
left: 0;
margin-top: 0;
min-width: 100%;
opacity: 0.94;
transition: opacity .5s ease-out;
}
</style>
JS
<script type="text/javascript">
$(function() {
$(window).scroll(function() {
if ($(this).scrollTop() > 495) { /* 要滑動到選單的距離 */
$('.dropdowns').addClass('navFixed'); /* 幫選單加上固定效果 */
} else {
$('.dropdowns').removeClass('navFixed'); /* 移除選單固定效果 */
}
});
});
</script>
HTML
<div class="navFixed" ></div>
參考來源: https://edwardzou.blogspot.com/2017/09/fixMenu.html
2019年9月11日 星期三
2019年3月12日 星期二
CI cookies, session, cache memo
在CodeIgniter中頻繁使用Model在資料量大使用量高的EC網站是不好的選擇,可是EC網站的資料也不適合用靜態頁來處理,畢竟有許多互動的設計若是使用靜態頁那麼就失去意義了,某些(聯絡我們, 用戶條款)之類的到是很適合。
Ex. $this->output->cache($n);
delete_cookie('cookname');
Ex. $this->output->cache($n);
放置在Controler的 $this->load->view($action, $data); 前。
首先在config/autoload.php裡面需要加入相關的help
$autoload['helper'] = array('cookie');
寫入
set_cookie('cookname', $cookdata, 3600);
取得
get_cookie('cookname')
刪除delete_cookie('cookname');
於多網站共用Code的使用案例上,可是當使用prefix前綴來避免衝突/讀取錯誤的情事。
※全域設定可在 application/config/config.php 檔案中所設置的前綴 $config[‘cookie_prefix’]
※容量(size)大概4K使用,所以資料量大的話會無法儲存,存放於用戶端的瀏覽器內所以瀏覽器有限制存取時會無法使用。
取得
$this->session->userdata('sessionname')
$this->load->driver('cache'));
寫入$this->cache->save('cachename', $cookdata, 300); //300=5min
取得
$this->cache->get('cachename')
刪除
$this->cache->delete('cachename');
首先在config/autoload.php裡面需要加入相關的help
$autoload['libraries'] = array('session');
寫入
$this->session->set_userdata('sessionname', $cookdata);取得
$this->session->userdata('sessionname')
刪除
$this->session->unset_userdata('sessionname');
$this->session->unset_userdata('sessionname');
※ 容量(size)大概較Cookies大些但若是無法儲存則表示資料量超過容量限制,另外資料存放在記憶體內,伺服器記憶體管理務必注意。
cache:$this->load->driver('cache'));
寫入$this->cache->save('cachename', $cookdata, 300); //300=5min
取得
$this->cache->get('cachename')
刪除
$this->cache->delete('cachename');
※ 使用檔案儲存所以資料量不用擔心,不過因為是FILE所以I/O讀取的效率就偏低。
2019年1月9日 星期三
微信支付 By API 異常排除
近期在套用微信支付API碰到"數位簽章校驗不通過"的回覆困擾許久,程式碼檢查再檢查與文件對應都看不出所以然來,在檢視機台終端交易密鑰的更新Log發現相同程式碼下不同的終端編號會有不同的結果,若干編號就是回校驗不通過。
經查API文件僅敘述簽名檔做好SHA256運算後再以base64編碼置入sign中,此一現象在此網誌所述雷同,於是在base64編碼後在加上urlencode()後傳出,問題就排除了。
$hashValue= hash('sha256', $string, TRUE);
$sign=urlencode(base64_encode($hashValue));
小記:系統整合尤其是透過API交換資料的情況下,這類問題往往很難從單一方面去排除,尤其在另一方(內地? 代理的銀行端? 有聽沒有懂的客戶? )已讀不回或不讀不回下僅能以trial and error方式來排除,恩恩...期間所遭遇個管理層級與客戶層級的質問心酸,只能共勉之...
經查API文件僅敘述簽名檔做好SHA256運算後再以base64編碼置入sign中,此一現象在此網誌所述雷同,於是在base64編碼後在加上urlencode()後傳出,問題就排除了。
$hashValue= hash('sha256', $string, TRUE);
$sign=urlencode(base64_encode($hashValue));
小記:系統整合尤其是透過API交換資料的情況下,這類問題往往很難從單一方面去排除,尤其在另一方(內地? 代理的銀行端? 有聽沒有懂的客戶? )已讀不回或不讀不回下僅能以trial and error方式來排除,恩恩...期間所遭遇個管理層級與客戶層級的質問心酸,只能共勉之...
2019年1月4日 星期五
處理 curl call error(77) error(60) 備忘!
這陣子發生呼叫API無回應但API也沒有LOG(所以是沒有呼叫到API),後來在WEB端的Log檔看到crul回傳 err 77的記錄。
這個狀況因為只出現在特定機器上,所以看來非佈署問題與程式碼bug,新客戶網站後來新增SSL,但只用service nginx reload讓他生效並未執行service php-fpm restart,檢視SERVER運行時間已經百餘日也沒重啟過,所已將php-fpm重啟後就不會再發生相同的錯誤回報。
補充: 頁面使用JQuery(非同步)機制雖然能減少與伺服器端的資料交換量,可若啟用CSRF機制時若timeout時間設定太短而頁面太久沒有reload,會造成瀏覽者有頁面沒反應的情況,這部分在設計時需要檢查回傳值若為token過期狀態,則須強制頁面reload更新token已利正確運行。
使用curl增加設定:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0)
使用file_get_contents增加設定:
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
file_get_contents($target,false,stream_context_create($arrContextOptions));
2018年9月18日 星期二
Codeigniter使用OracleDB 備忘
1. 下載 Oracle Instant Client,建議下載32位元的貌似使用在Windows環境下的PHP的php_oci12c.dll是編譯在32位元的,當然自行下載source code編譯的就依照自己設定的為主。
※ 透過phpinfo()看所安裝的PHP是x86 or 64然後下載相對應的Oracle Client版本回來,不過通常是32位元的就是了。
2. 將下載回來的Oracle Client (建議:Instant Client Package - Basic )解壓縮後的路徑位址( N:\instantclientXX\ ) 新增到系統環境變數內,請記得重新開機以利生效。
3. 至php.ini將php_oci12c.dll前面的分號";"拿掉,然後重啟web server(ex. IIS or Apache)。
4. 在CI的config\database.php
$db['default'] = array(
'dsn' => '',
'hostname' => '(IP or DomainName)/(SID)',
'username' => 'account',
'password' => '******',
'database' => '',
'dbdriver' => 'oci8',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
5. 若依舊是顯示oci_connect() 未定義的錯誤,那麼就再下載含有Net Manager 的 Oracle Client。之前碰到Oracle Client裝64位元但:Instant Client裝x86,這樣PHP是沒法啟用oci8的套件。
備忘:
1. 改Oracle後table & column name都變大寫,好用的AI沒了得改sys_guid() ... 還有很多很多 =.=
2. CI在Sql Query會加雙引號,若使用Oracle須改system\db_driver.php 把雙引號拿掉。
3. CI2使用Oracle是悲劇的(ex. rownum()),後來直接改使用CI3就順多了。
※ 透過phpinfo()看所安裝的PHP是x86 or 64然後下載相對應的Oracle Client版本回來,不過通常是32位元的就是了。
3. 至php.ini將php_oci12c.dll前面的分號";"拿掉,然後重啟web server(ex. IIS or Apache)。
4. 在CI的config\database.php
$db['default'] = array(
'dsn' => '',
'hostname' => '(IP or DomainName)/(SID)',
'username' => 'account',
'password' => '******',
'database' => '',
'dbdriver' => 'oci8',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => (ENVIRONMENT !== 'production'),
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
5. 若依舊是顯示oci_connect() 未定義的錯誤,那麼就再下載含有Net Manager 的 Oracle Client。之前碰到Oracle Client裝64位元但:Instant Client裝x86,這樣PHP是沒法啟用oci8的套件。
備忘:
1. 改Oracle後table & column name都變大寫,好用的AI沒了得改sys_guid() ... 還有很多很多 =.=
2. CI在Sql Query會加雙引號,若使用Oracle須改system\db_driver.php 把雙引號拿掉。
3. CI2使用Oracle是悲劇的(ex. rownum()),後來直接改使用CI3就順多了。
2018年3月20日 星期二
夯名詞:新零售, 區塊鏈, 人工智慧有感
最近聽得多CI BI AI,這類高來高去的名詞,身為一位相對務實的開發人員,對於這些總是環繞在怎麼做到~做到了又如何應用的死循環中。
先有需求再建構/配合模型,自所擁有的管道(軟體服務)蒐集(CI)有用的RAW DATA,送入模型後得到BI(商業智慧),進送入機器學習建構資源庫未來依此來判別(AI),感覺上好像是在消滅自己工作一樣,一但有了AI那麼系統開發作業不就會被代勞嗎(=.= 真是想太多了,不過工程師有個好處,沒有理論支援下產出的工人智慧,對某些人來看也會被美化成人工智慧)。
AI在課堂中最早是從類神經網路的建構,透過訓練方式來歸納出許多的 pattern,這些在依照所配得權重以計算出最合適的結果,恩恩...這樣看來如何取代工作呢? 不過市場上所有產品都是需要包裝的,當軟體要搭上這股熱潮再不打算大改的情況下,只好再透過重新包裝來應付,但這些也是得燒掉多的腦細胞。
新零售也是如此,貌似"無人商店"也得沾上一點邊,亞馬遜所提的概念店面東改西湊(東施效顰的概念),別人有的都加進來沒有的就是優勢? 不過所看的到的都是表象,技術這類的潘朵拉之盒卻得不到;在區塊鏈上因bitcoin而廣受討論,兩個相加起來就是如何去中間話在新零售上,生產->配銷->消費者的概念把中間的"經銷商"由軟體系統取代掉,讓消費者能快速取得新鮮品優的產品(當然能做到價廉就更不可思議了),可現實真是能如此嗎? 大家都覺得經銷商賺得飽飽的(Ex. 專門剝削生產端宰殺消費者的菜蟲?),但是許多事情都有他不為人知的專業在,各個環節所需承擔的風險成本往往是被忽視的,用軟體系統+AI來處理掉中間人學術討論上總是誘人的,回歸現實就傷腦筋囉...
拜讀21世紀資本論(超厚)比起看富爸爸窮爸爸系列來的有感,資本市場講求的看中的或許底蘊有那麼1%重要的,其他99%就不是腦袋硬梆梆只會硬幹的人能去求的,當創造話題的大老們衝在前頭,後頭收尾的工程師們...除了爆些新鮮個肝賺取微薄的OO之外,就只能幻想"有夢最美希望相隨"不是口號的一天,呵呵。
~~有段順口溜流傳許久,繼續做自我看著笑笑即可 ~~
東混西混,一帆風順; 苦幹實幹,撤職查辦;
盡職負責,卻遭指責; 任勞任怨,永難如願;
推拖栽贓,滿排勳章; 屢建奇功,打入冷宮;
不拍不吹,狗屎一堆; 全力以赴,升遷耽誤;
苦苦哀求,互踢皮球; 看緊國庫,馬上解僱;
會捧會現,傑出貢獻; 會鑽會溜,考績特優。
先有需求再建構/配合模型,自所擁有的管道(軟體服務)蒐集(CI)有用的RAW DATA,送入模型後得到BI(商業智慧),進送入機器學習建構資源庫未來依此來判別(AI),感覺上好像是在消滅自己工作一樣,一但有了AI那麼系統開發作業不就會被代勞嗎(=.= 真是想太多了,不過工程師有個好處,沒有理論支援下產出的工人智慧,對某些人來看也會被美化成人工智慧)。
AI在課堂中最早是從類神經網路的建構,透過訓練方式來歸納出許多的 pattern,這些在依照所配得權重以計算出最合適的結果,恩恩...這樣看來如何取代工作呢? 不過市場上所有產品都是需要包裝的,當軟體要搭上這股熱潮再不打算大改的情況下,只好再透過重新包裝來應付,但這些也是得燒掉多的腦細胞。
新零售也是如此,貌似"無人商店"也得沾上一點邊,亞馬遜所提的概念店面東改西湊(東施效顰的概念),別人有的都加進來沒有的就是優勢? 不過所看的到的都是表象,技術這類的潘朵拉之盒卻得不到;在區塊鏈上因bitcoin而廣受討論,兩個相加起來就是如何去中間話在新零售上,生產->配銷->消費者的概念把中間的"經銷商"由軟體系統取代掉,讓消費者能快速取得新鮮品優的產品(當然能做到價廉就更不可思議了),可現實真是能如此嗎? 大家都覺得經銷商賺得飽飽的(Ex. 專門剝削生產端宰殺消費者的菜蟲?),但是許多事情都有他不為人知的專業在,各個環節所需承擔的風險成本往往是被忽視的,用軟體系統+AI來處理掉中間人學術討論上總是誘人的,回歸現實就傷腦筋囉...
拜讀21世紀資本論(超厚)比起看富爸爸窮爸爸系列來的有感,資本市場講求的看中的或許底蘊有那麼1%重要的,其他99%就不是腦袋硬梆梆只會硬幹的人能去求的,當創造話題的大老們衝在前頭,後頭收尾的工程師們...除了爆些新鮮個肝賺取微薄的OO之外,就只能幻想"有夢最美希望相隨"不是口號的一天,呵呵。
~~有段順口溜流傳許久,繼續做自我看著笑笑即可 ~~
東混西混,一帆風順; 苦幹實幹,撤職查辦;
盡職負責,卻遭指責; 任勞任怨,永難如願;
推拖栽贓,滿排勳章; 屢建奇功,打入冷宮;
不拍不吹,狗屎一堆; 全力以赴,升遷耽誤;
苦苦哀求,互踢皮球; 看緊國庫,馬上解僱;
會捧會現,傑出貢獻; 會鑽會溜,考績特優。
2018年2月9日 星期五
Nginx return 405 error
最近搬移伺服器,WEB伺服器也同步將Apache改成Nginx,客戶回報標籤列印軟體出現異常無法同步更新,Debug後看到回傳405錯誤,可該URL直接呼叫卻是能取得資料的,爬了些文看到解法...
於conf檔中新增error_page 405 =200 $request_uri;後重啟nginx排除掉問題。
location / {
error_page 405 =200 $request_uri;
try_files $uri $uri/ /petel/index.php;
}
至於後來想想為什麼要用POST方式而不使用GET方式取呢? 往常POST請求也可以做到GET請求的回覆,所以從程式碼共用/使用的方向來想也挺合理的,只不過Apache沒出這種問題吧。
於conf檔中新增error_page 405 =200 $request_uri;後重啟nginx排除掉問題。
location / {
error_page 405 =200 $request_uri;
try_files $uri $uri/ /petel/index.php;
}
至於後來想想為什麼要用POST方式而不使用GET方式取呢? 往常POST請求也可以做到GET請求的回覆,所以從程式碼共用/使用的方向來想也挺合理的,只不過Apache沒出這種問題吧。
2018年2月2日 星期五
透過CKEditor或Summernote上傳iphone拍的圖片顯示被轉向問題
Bootstrap的RWD設計很方便,不過開發狀況上要考慮的點就挺多的,客戶反映說手機上圖時顯示是反的,但是圖下載下來是正的,乍聽之下挺神奇的不是事實卻是如此。
爬文得知在iphone手機拍攝照片時,會取決於拍照按鈕位置來存檔,所以在圖片的Orientation的狀態上就可能是旋轉的,不過在PC檢視上通常會自動轉回來可是瀏覽器就...參考網誌
另外因為手機的鏡頭跟效能越來越強,所以照片的解析度SIZE變超大,看起來是很舒服不過在WEB應用上就挺占頻寬的,簡單的壓縮功能就一併去實現囉。
//圖檔壓縮與旋轉
function image_resize($targetFile){
if (file_exists($targetFile)){
$img_array = getimagesize($targetFile);
$isResize = false;
$ratio = 512;
if ($img_array[0] > $ratio){
$config['width'] = $ratio;
$height = $img_array[1] / ($img_array[0] / $ratio);
$config['height'] = intval($height);
$isResize = true;
} else if ($img_array[1] > $ratio){
$config['height'] = $ratio;
$width = $img_array[0] / ($img_array[1] / $ratio);
$config['width'] = intval($width);
$isResize = true;
}
if ($isResize){
$this->load->library('image_lib');
$config['image_library'] = 'gd2';
$config['source_image'] = $targetFile;
$config['maintain_ratio'] = TRUE;
//because iphone photo maybe save rotation by sensor
$exif = @exif_read_data($targetFile);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$config['rotation_angle'] = '90';
break;
case 3:
$config['rotation_angle'] = '180';
break;
case 6:
$config['rotation_angle'] = '270';
break;
}
$this->image_lib->initialize($config);
$this->image_lib->rotate();
}
$config['rotation_angle'] = '0';
$this->image_lib->initialize($config);
$this->image_lib->resize();
}
return true;
} else {
return false;
}
}
爬文得知在iphone手機拍攝照片時,會取決於拍照按鈕位置來存檔,所以在圖片的Orientation的狀態上就可能是旋轉的,不過在PC檢視上通常會自動轉回來可是瀏覽器就...參考網誌
另外因為手機的鏡頭跟效能越來越強,所以照片的解析度SIZE變超大,看起來是很舒服不過在WEB應用上就挺占頻寬的,簡單的壓縮功能就一併去實現囉。
//圖檔壓縮與旋轉
function image_resize($targetFile){
if (file_exists($targetFile)){
$img_array = getimagesize($targetFile);
$isResize = false;
$ratio = 512;
if ($img_array[0] > $ratio){
$config['width'] = $ratio;
$height = $img_array[1] / ($img_array[0] / $ratio);
$config['height'] = intval($height);
$isResize = true;
} else if ($img_array[1] > $ratio){
$config['height'] = $ratio;
$width = $img_array[0] / ($img_array[1] / $ratio);
$config['width'] = intval($width);
$isResize = true;
}
if ($isResize){
$this->load->library('image_lib');
$config['image_library'] = 'gd2';
$config['source_image'] = $targetFile;
$config['maintain_ratio'] = TRUE;
//because iphone photo maybe save rotation by sensor
$exif = @exif_read_data($targetFile);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$config['rotation_angle'] = '90';
break;
case 3:
$config['rotation_angle'] = '180';
break;
case 6:
$config['rotation_angle'] = '270';
break;
}
$this->image_lib->initialize($config);
$this->image_lib->rotate();
}
$config['rotation_angle'] = '0';
$this->image_lib->initialize($config);
$this->image_lib->resize();
}
return true;
} else {
return false;
}
}
2017年10月18日 星期三
CKEDITOR在Bootstrap Model中功能視窗跳到背景的FIX
套用RWD頁面很方便,但有些眉眉角角就得特別處理,CKEDITOR很好用兩個勾稽在一起,熊熊發現不是那麼的圓滿,當然官方也是都有解的,要找而已...Memo囉。
大體來講這個問題出在版面上,所以調整上還是不脫CSS跟JS的配合。
解決方式:
CSS
<style type="text/css">
/* (style-metronic)modal conflict with popup of ckeditor (fix) */
.modal-backdrop {
z-index: 1040 !important;
}
.modal {
z-index: 1050 !important;
}
</style>
JS
<script>
// CKEditor Link input not working in bootstrap modal (fix)
$.fn.modal.Constructor.prototype.enforceFocus = function () {
var $modalElement = this.$element;
$(document).on('focusin.modal',
function (e) {
var $parent = $(e.target.parentNode);
if ($modalElement[0] !== e.target &&
!$modalElement.has(e.target).length &&
!$parent.hasClass('cke_dialog_ui_input_select') &&
!$parent.hasClass('cke_dialog_ui_input_text')) {
$modalElement.focus();
}
});
};
</script>
大體來講這個問題出在版面上,所以調整上還是不脫CSS跟JS的配合。
解決方式:
CSS
<style type="text/css">
/* (style-metronic)modal conflict with popup of ckeditor (fix) */
.modal-backdrop {
z-index: 1040 !important;
}
.modal {
z-index: 1050 !important;
}
</style>
JS
<script>
// CKEditor Link input not working in bootstrap modal (fix)
$.fn.modal.Constructor.prototype.enforceFocus = function () {
var $modalElement = this.$element;
$(document).on('focusin.modal',
function (e) {
var $parent = $(e.target.parentNode);
if ($modalElement[0] !== e.target &&
!$modalElement.has(e.target).length &&
!$parent.hasClass('cke_dialog_ui_input_select') &&
!$parent.hasClass('cke_dialog_ui_input_text')) {
$modalElement.focus();
}
});
};
</script>
2017年6月29日 星期四
PHP的file_get_contents 逾時操作
在PHP中file_get_contents蠻常用到的,需要注意的地方大概就是在php.ini裡需要將allow_url_fopen = on,還有就是User Agent偽裝一下
ini_set('user_agent','Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0')
ini_set('user_agent','Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0')
不過最近發現到如果呼叫的url過大,就有一定的機率回500錯誤 Orz...
解決方法:
GET:
$opts = array(
'http'=>array(
'method'=>"GET",
'timeout'=>600,
)
);
$context = stream_context_create($opts);
file_get_contents($target_url, false, $context);
POST:
function Post($url, $post = null)
{
$context = array();
if (is_array($post)) {
ksort($post);
$context['http'] = array (
'timeout'=>600,
'method' => 'POST',
'content' => http_build_query($post, '', '&'),
);
}
return file_get_contents($target_url, false, stream_context_create($context));
}
$data = array (
'name' => 'test',
'email' => 'test@gmail.com',
'submit' => 'submit',
);
Post('http://www.example.com', $data);
加上TimeOut時間就能避免了,不過就是等久了些使用者會不耐煩。在JQuery的非同步執行下~等久了有若干機會造成DB的Deadlock狀態(透過呼叫API同步資料再搭配系統操作...)。
PS. 建議使用curl或fsockopen來處理,file_get_contents用起來簡單但是其缺點也是挺無奈地,萬一主機商不給改php.ini 或是資料量大或運算/執行較久的頁面,那Debug起來不方便。
2017年1月5日 星期四
用資料用JSON編碼搭配POST方式的交換機制~備忘
與異質平台整合(如金流)碰上資料交遞上的方法,有時資料封裝得做JSON編碼不是直接參數名送出,因此寫個MEMO幫助記憶...
傳送時...
1. 首先是資料傳遞的FUNC ,$Url是目的地、$post就是交換的資料,若要改成GET則調整CURLOPT_CUSTOMREQUEST設定即可。timeout時間故意調長,因為碰上timeout錯誤時很殘念的。
function PostData($Url, $post){
$ch = curl_init($Url);
$headers = array(
'Content-Length:'.strlen($post),
'Content-type: application/json'
);
//print_r($headers);
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => 1,
CURLOPT_CUSTOMREQUEST=>"POST",
CURLOPT_POSTFIELDS=> $post,
CURLOPT_HTTPHEADER=> $headers,
CURLOPT_TIMEOUT=>500,
CURLOPT_CONNECTTIMEOUT=>5
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
if(curl_errno($ch)!=0){
trigger_error(curl_error($ch));
}
curl_close($ch);
return $result;
}
2. 傳遞參數封裝,做成陣列即可...弄複雜些給個陣列包陣列的sample
$params_data = array(
'order_no' => $order_no,
'amt' => $amt,
'result_url' => $result_url
);
$order_data = array (
'sender' => "rest",
'ver' => "1.0.0",
'tx_type' => 1,
'params' => $params_data
);
3. 開始傳遞
PostData($URL, json_encode($order_data));
接收時....
1. 首先...因為不知道傳回來的是啥變數名,只知道是個JSON串,所以通通一起收php://input是蠻方便的方式。
$post_data = file_get_contents("php://input");
2. 拆解JSON取得資料,原則上卡關較久的是array裡面的array資料讀取。
$j_result = json_decode($post_data);
$data = array(
'order_no'=> $j_result->params->order_no,
'sender'=> $j_result->sender,
);
2016年10月5日 星期三
codeigniter csrf機制設定
串接金流後...想找些避免被有心人士誤用的頁面稽核機制,除了原有的那些措施之外,有文章推薦可啟用在 CI 2.0的 csrf(Cross Site Request Forgery) protection 功能。
設定 application\config\config.php將csrf打開
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
接著在View中如果有需要提交的Form則使用form_open(action, variable array)來寫就會直接產生相關的Code,真方便。
不過...如果有接收金流的Return Url時,會出現不給接收的Message(謎之聲~當然因為金流公司不會送相關的稽核Code過來。
解法:
設定 application\config\config.php中改寫為
if (stripos($_SERVER["REQUEST_URI"],'controler name/function name') === FALSE) {
$config['csrf_protection'] = TRUE;
else
$config['csrf_protection'] = FALSE;
這樣就能有例外情況了。
另外如果不想使用form_open()要手動來的話~找到的範例如下。
$(function(){
$('#btn').click(function(){
$.ajax({
type:'POST'
,url:'/ajax' //ajax接收的server端
,data:$('#form').serialize()+'&csrf_test_name='+ getCookie('csrf_test_name')
,success:function(data){
alert(data.msg);
}
,dataType:'json'
});
});
});
function getCookie(name){
var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
if(arr != null) return unescape(arr[2]); return null;
}
設定 application\config\config.php將csrf打開
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
接著在View中如果有需要提交的Form則使用form_open(action, variable array)來寫就會直接產生相關的Code,真方便。
不過...如果有接收金流的Return Url時,會出現不給接收的Message(謎之聲~當然因為金流公司不會送相關的稽核Code過來。
解法:
設定 application\config\config.php中改寫為
if (stripos($_SERVER["REQUEST_URI"],'controler name/function name') === FALSE) {
$config['csrf_protection'] = TRUE;
else
$config['csrf_protection'] = FALSE;
這樣就能有例外情況了。
另外如果不想使用form_open()要手動來的話~找到的範例如下。
$(function(){
$('#btn').click(function(){
$.ajax({
type:'POST'
,url:'/ajax' //ajax接收的server端
,data:$('#form').serialize()+'&csrf_test_name='+ getCookie('csrf_test_name')
,success:function(data){
alert(data.msg);
}
,dataType:'json'
});
});
});
function getCookie(name){
var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
if(arr != null) return unescape(arr[2]); return null;
}
2016年8月25日 星期四
phpmailer 無法寄信狀況排除的備忘
首先...先測試伺服器連線是否正常
yum install telnet <- 安裝telnet套件
telnet DomainName 25 ... 要有回應,輸入Quit跳開
其次可能是SELinux擋掉,所以使用
getsebool httpd_can_sendmail ... 必須是ON
如果是OFF則使用 setsebool httpd_can_sendmail=1
yum install telnet <- 安裝telnet套件
telnet DomainName 25 ... 要有回應,輸入Quit跳開
其次可能是SELinux擋掉,所以使用
getsebool httpd_can_sendmail ... 必須是ON
如果是OFF則使用 setsebool httpd_can_sendmail=1
貌似歧途...
有網友提到可能是openssl造成,前提必須是認證使用TLS或SSL
透過php -i檢查是否有支援openssl,如果沒有就安裝並將openssl.so enable.
CodeIgniter 網址列 index.php去除備忘
之前嘗試失敗的今天成功了,備忘一下...主要差別在httpd.conf AllowOverride沒設成 ALL所致。現在URL看起來清爽多了。
1. ../.htaccess增加
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
1. ../.htaccess增加
DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
2. 在../application/config/config.php
$config['index_page'] = ''; 原:'index.php'
$config['index_page'] = ''; 原:'index.php'
3. vim httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so => 去掉#
AllowOverride None=> AllowOverride All
At Ubuntu 16.04
aptitude reinstall apache2.2-common
a2enmod headers
sudo a2enmod rewrite
service apache2 restart
AllowOverride None=> AllowOverride All
At Ubuntu 16.04
aptitude reinstall apache2.2-common
a2enmod headers
sudo a2enmod rewrite
service apache2 restart
2016年7月26日 星期二
CodeIgniter套用language備忘
在CI預設FrameWork是沒加上語系表,不過語系表方便多國語言套用~這很好用就Memo一下!!
在language新增相關語系資料夾 etc: en, zh ...
在config
: autoload
$autoload['model'] = array('Appconfig', ...
:config
$config['language'] = 'zh';
:hooks
$hook['post_controller_constructor'] = array(
'class' => '',
'function' => 'load_config',
'filename' => 'load_config.php',
'filepath' => 'hooks'
);
在model
新增appconfig.php
class Appconfig extends CI_Model {
function exists($key)
{
$this->db->from('app_config');
$this->db->where('app_config.key',$key);
$query = $this->db->get();
return ($query->num_rows()==1);
}
function get_all()
{
$this->db->from('app_config');
$this->db->order_by("key", "asc");
return $this->db->get();
}
function get($key)
{
$query = $this->db->get_where('app_config', array('key' => $key), 1);
if($query->num_rows()==1)
{
return $query->row()->value;
}
return "";
}
function save($key,$value)
{
$config_data=array(
'key'=>$key,
'value'=>$value
);
if (!$this->exists($key))
{
return $this->db->insert('app_config',$config_data);
}
$this->db->where('key', $key);
return $this->db->update('app_config',$config_data);
}
function batch_save($data)
{
$success=true;
//Run these queries as a transaction, we want to make sure we do all or nothing
$this->db->trans_start();
foreach($data as $key=>$value)
{
if(!$this->save($key,$value))
{
$success=false;
break;
}
}
$this->db->trans_complete();
return $success;
}
function delete($key)
{
return $this->db->delete('app_config', array('key' => $key));
}
function delete_all()
{
return $this->db->empty_table('app_config');
}
}
在language新增相關語系資料夾 etc: en, zh ...
在config
: autoload
$autoload['model'] = array('Appconfig', ...
:config
$config['language'] = 'zh';
:hooks
$hook['post_controller_constructor'] = array(
'class' => '',
'function' => 'load_config',
'filename' => 'load_config.php',
'filepath' => 'hooks'
);
在hook
新增load_config.php
function load_config(){
$CI =& get_instance();
foreach( $CI->Appconfig->get_all()->result() as $app_config )
{
$CI->config->set_item( $app_config->key, $app_config->value );
}
//Set language from config database
//Loads all the language files from the language directory
if ( $CI->config->item( 'language' ) )
{
$CI->config->set_item( 'language', $CI->config->item( 'language' ) );
$map = directory_map('./application/language/' . $CI->config->item( 'language' ));
foreach($map as $file)
{
if ( substr(strrchr($file,'.'),1) == "php")
{
$CI->lang->load( str_replace( '_lang.php', '', $file ) );
}
}
}
//Set timezone from config database
if ( $CI->config->item( 'timezone' ) )
{
date_default_timezone_set( $CI->config->item( 'timezone' ) );
}
else
{
date_default_timezone_set( 'America/New_York' );
}
}
新增appconfig.php
class Appconfig extends CI_Model {
function exists($key)
{
$this->db->from('app_config');
$this->db->where('app_config.key',$key);
$query = $this->db->get();
return ($query->num_rows()==1);
}
function get_all()
{
$this->db->from('app_config');
$this->db->order_by("key", "asc");
return $this->db->get();
}
function get($key)
{
$query = $this->db->get_where('app_config', array('key' => $key), 1);
if($query->num_rows()==1)
{
return $query->row()->value;
}
return "";
}
function save($key,$value)
{
$config_data=array(
'key'=>$key,
'value'=>$value
);
if (!$this->exists($key))
{
return $this->db->insert('app_config',$config_data);
}
$this->db->where('key', $key);
return $this->db->update('app_config',$config_data);
}
function batch_save($data)
{
$success=true;
//Run these queries as a transaction, we want to make sure we do all or nothing
$this->db->trans_start();
foreach($data as $key=>$value)
{
if(!$this->save($key,$value))
{
$success=false;
break;
}
}
$this->db->trans_complete();
return $success;
}
function delete($key)
{
return $this->db->delete('app_config', array('key' => $key));
}
function delete_all()
{
return $this->db->empty_table('app_config');
}
}
訂閱:
文章 (Atom)