2021年3月5日 星期五

php 同時傳送超過1000個變數時的做法


php 同時傳送超過1000個變數時,比方
<form id="myForm">
<?php
for ($i=0; $i <1200 ; $i++) {
  echo '<button type="submit">送出</button>';
}
?>
<form>
此時會報錯誤
PHP Warning:  Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini.
雖然可以照它說的去更改 max_input_var 的數字,但終歸無法一牢永逸(因為我的變數一直在增加)
所以上網找到這個解法:將1000個變數的值集中到一個變數中,接收後再拆開來使用


在 html 的部份,加上一變數,在送出前集中所有變數的值到此一變數
<input name="storeids" type="hidden" />
<button type="submit" onclick="changeidstostring();">送出</button>

在 js 的部份這樣寫
function changeidstostring() {
  $('#myForm').submit(function() {
    var storeids = $("input[name='ids[]']").map(function(){return $(this).val();}).get();
    $("input[name='storeids']").val(storeids);
    $("input[name='ids[]']").attr("disabled","disabled");	// 將原來會產生很多變數的元素disabled 掉,就不會傳送了 
  });
}
在接收的部分這樣寫
$ids = explode(",", $_POST['storeids']);  // 因為參數太多(超過1000個,所以改成先集中到某個參數,傳送過來再拆解)

2019年8月27日 星期二

PHP PDO IN 條件

使用PHP PDO 在組合查詢語法時若有 IN 條件,通常會用此方法
$myArray = array(1,2,3);
$in = trim(str_repeat('?,', count($myArray)),',');
$stm = $conn->prepare("SELECT * FROM table WHERE id IN ($in)");
$stm->execute($myArray);
萬一遇上 $myArray 的個數很多時,會造成語法太長,無法執行怎麼辦?
試試下面這個方法
$myArray = array(1,2,3);
$in = implode(',', $myArray);
$stm = $conn->prepare("SELECT * FROM table WHERE FIND_IN_SET(id, :inArray) ORDER BY name");
$stm->bindParam('inArray', $in);
$stm->execute();
如果是 not in,就加上一驚嘆號,變成 !FIND_IN_SET 就可以了
$myArray = array(1,2,3);
$in = implode(',', $myArray);
$stm = $conn->prepare("SELECT * FROM table WHERE !FIND_IN_SET(id, :inArray) ORDER BY name");
$stm->bindParam('inArray', $in);
$stm->execute();

2019年7月9日 星期二

使用 Gmail 的兩步驟認證下,透過 PHPMailer 發送郵件範例

到google 設定兩步驟認證
1.登入google後,找到 google帳戶,在"安全性"下會看到如下圖
未啟用兩步驟驗證的畫面

2.選擇上圖中的"兩步驟驗證"後,按下"開始使用"後,依照步驟操作完成,會得到一組16位數的密碼,此密碼會用於步驟三中的
$mail->Password = '密碼';

程式碼配置與發信程式撰寫(在沒有 composer 的環境下)
一、程式碼下載
1.到 github 上下載程式碼:PHPMailer,並解壓縮
解壓縮後資料夾內容
2.將 PHPMailer 資料夾放在自己知道的路徑下,比方:/var/www/mySite/PHPMailer

二、發信程式碼撰寫
<?php
try {
   /* Set the mail encode. */
   CharSet = 'UTF-8';

   /* Set the mail sender. */
   $mail->setFrom('寄件人@gmail.com', '寄件人名稱');

   /* Add a recipient. */
   $mail->addAddress('收件人郵件地址', '收件人名稱');

   /* Set the subject. */
   $mail->Subject = '主旨';

   /* Set the mail message body. */
   $mail->Body = '信件內容';

   /* SMTP parameters. */
   
   /* Tells PHPMailer to use SMTP. */
   $mail->isSMTP();
   
   /* SMTP server address. */
   $mail->Host = 'smtp.gmail.com';

   /* Use SMTP authentication. */
   $mail->SMTPAuth = TRUE;
   
   /* Set the encryption system. */
   $mail->SMTPSecure = 'tls';
   
   /* SMTP authentication username. */
   $mail->Username = '寄件人@gmail.com';
   
   /* SMTP authentication password. google 兩步驟認證的密碼*/
   $mail->Password = '密碼';
   
   /* Set the SMTP port. */
   $mail->Port = 587;

   /* Finally send the mail. */
   $mail->send();

   echo "成功發送信件!";
}
catch (Exception $e)
{
   echo "發送失敗!";
   /* PHPMailer exception. */
   echo $e->errorMessage();
}
catch (\Exception $e)
{
   echo "發送失敗!";
   /* PHP exception (note the backslash to select the global namespace Exception class). */
   echo $e->getMessage();
}
?>

https://alexwebdevelop.com/phpmailer-tutorial/ 阿力獅的教室

2019年3月28日 星期四

php 將接收 POST 來的資料放到 html 元素中要注意的地方

事情是這樣的,因為某些因素,要 POST 的資料包含 HTML 中的 TAG 符號,如下
$str = "<option value="1">student</option><option value="2">teacher</option><option value="3">teachers' office</option>";
在接收資料時,要將它還原成一下拉選單,如下
<select id="select_1">
<option value="1">student</option>
<option value="2">teacher</option>
<option value="3">teachers' office</option>
</select>
但是因為文字中有特殊符號  ' ,造成只能顯示
<select id="select_1">
<option value="1">student</option>
<option value="2">teacher</option>
<option value="3">teachers

上網 google 了一下後,修改方式:
在 POST 前用 htmlentities 將資料包起來,這樣接收時就可以正常了


[PHP] HTML特殊字元轉換

2019年1月29日 星期二

php 的日期比較

在比對之前,先說明一下如何得到目前日期 在 php 5.2(含) 前可以用 date('Y-m-d') 在 php 5.2(不含) 後可以用 new DateTime() 雖然函數有一點點不同,但都需要注意時區可能產生的問題

接下來開始比較日期
使用函數 strtotime
$Date1 = date('Y-m-d'); 
$Date2 = '9999-12-31';
if(strtotime($Date1) > strtotime($Date2)) { 
  echo 'Date1 較新'; 
} 
else { 
  echo 'Date2 較新'; 
} 
基本上這樣就可以了,但是若是使用XAMPP,上面的語法可能會出現錯誤,原因在於 Y2K38漏洞,也被稱為Unix Millennium Bug,也就是 strtotime 只認得 2038-1-19 03:14:07 之前的日期時間,在此日期時間後的就會溢位,進而產生錯誤。

所以將語法修改如下,順便用了 php 5.2 版之後的語法
$Date1 = date_format(new DateTime(),'U'); 
// $Date2 = date_format(new DateTime('9999-12-31'),'U');
// 這邊需要注意因為 DateTime()會包含時間的部分,所以在比較時要同時加上時間的部分(或去除時間的部分)來比較會較正確,
// 或是將 $Date2 多加一天後再比較也行,所以將 $Date2 修改一下
$Date2 = date_format(date_modify(new DateTime('9999-12-31'),'+1 days'),'U');
if($Date1 > $Date2) { 
  echo 'Date1 較新'; 
} 
else { 
  echo 'Date2 較新'; 
} 
藍色小舖 php 討論區- 日期的比較 PHP轉換超過2038年的日期出錯問題解決

用Temp Table取代Cursor

cursor通常用來逐筆處理資料使用,下面是一個簡單的範例(MS SQL Server 2008)
declare @myId int
declare @myName nvarchar(20)
declare @myCursor CURSOR

set @myCursor = CURSOR FAST_FORWARD
FOR
SELECT ID, NAME FROM Employee
open @myCursor
INTO @myId, @myName
WHILE @@FETCH_STATUS = 0
BEGIN

    --DO SOMETHING

    FETCH NEXT FROM @myCursor
    INTO @myId, @myName

END

CLOSE @myCursor
DEALLOCATE @myCursor
用temp table來模擬cursor的操作模式,簡單的說就是把SELECT ID, NAME FROM Employee的結果存到temp table中,在逐步讀取,所以必須先建立一個temp table如下
create table #tempEmployee
(
    ID int,
    NAME nvarchar(20)
)
然後把資料insert into select 到 #tempEmployee
insert into #tempEmployee (ID,NAME)
select ID,NAME
from Employee
接下來,就是逐步讀取這個temp table #tempEmployee
在MS SQL Server中使用SET ROWCOUNT 1來控制select時一次只撈出一筆資料,而且每做完一筆就刪掉,直到#tempEmployee沒有資料為止
declare @countTemp int --用來計算#tempEmployee還剩幾筆資料

--計算#tempEmployee資料數
select @countTemp = count(*) from #tempEmployee

while(@countTemp > 0)
begin
    set rowcount 1
    select @myId = ID, @myName = NAME from #tempEmployee
    --To Something
     
    --因為set rowcount 1的關係,所以一次只會刪一筆
    delete from #tempEmployee 

    --計算還剩幾筆,@countTemp > 0繼續
    select @countTemp = count(*) from #tempEmployee  
end

--#刪除 tempEmployee
drop table #tempEmployee

--把select的預設比數恢復正常
set rowcount 0
如此一般,完整的程式碼如下
declare @myId int
declare @myName nvarchar(20)

create table #tempEmployee
(
    ID int,
    NAME nvarchar(20)
)

declare @countTemp int --用來計算#tempEmployee還剩幾筆資料

--計算#tempEmployee資料數
select @countTemp = count(*) from #tempEmployee

while(@countTemp > 0)
begin
    set rowcount 1
    select @myId = ID, @myName = NAME from #tempEmployee
    --To Something
     
    --因為set rowcount 1的關係,所以一次只會刪一筆
    delete from #tempEmployee 

    --計算還剩幾筆,@countTemp > 0繼續
    select @countTemp = count(*) from #tempEmployee  
end

--#刪除 tempEmployee
drop table #tempEmployee
遜砲賴的爆肝筆記-stored procedure中不使用cursor逐步讀取資料列的方法

2018年4月29日 星期日

不爽 0002

總: 董事長剛吃完飯,等等讓他吃藥
我: 好(看了一下桌面),只有一個杯子?
總: 對,你到底有沒有在顧(用心)?飯後都只有一杯藥
我: 有啊(心想早上明明看到2個杯子的藥,還是我看錯了?)
(之後)
總: 你...
我: 嗯(不想回答有意義的文字了)


(中午,問了一下護理師)
我: 請問早上餐後的藥是一杯還兩杯?
護: 兩杯呵,一杯裡面三顆藥,一杯喝的
我: 謝謝。(心想,掯!早上總經理是在唸不爽的嗎?到底是誰沒在顧?)