2020年11月16日 星期一

數莓派 透過macbook網路連線數莓派

MAC上需要安裝nmap來查詢連線的數莓派IP

- 進入終端機輸入:

- brew install nmap

然後到 mac 系統偏好設定> 網路

-啟用網路DHCP,會需要跑一陣子,當IP出現後表示已連線數莓派(數莓派要先開機)



接著到mac 系統偏好設定> 共享

-啟用Internet共享給數莓派


回到終端機先查詢本機IP

- $ifconfig

- 會列出很多裝置的位置,但這邊要查的是網路線裝置的位置如下bridge100,可以在Inet中看到192.168.2.1



使用nmap查詢數莓派位置

- 因為已經知道DHCP分享的本機位置了,數莓派會在同網段

- $sudo nmap -n -sP 192.168.2.1/255

- 就會看到他列出192.168.2.2的數莓派IP


接下來可以透過SSH或VNC連線數莓派

SSH連線:

- $ ssh pi@[ip] 

- 再輸入密碼


VNC連線:

- finder>前往>連線伺服器

- vnc://IP

詳見mac VNC連線

數莓派 mac VNC 連線Pi4 (解決VNC 版本不相容問題)

數莓派要先安裝vncserver, Viwer

sudo apt-get install realvnc-vnc-server real-vnc-viewer


安裝後變更數莓派VNC介面設定為啟用


啟用VNC server

$sudo raspi-config

- 選擇Interface Option

- 選擇VNC,然後確認啟用




進入VNC設定視窗

- 點擊數莓派視窗右上角的 VNC Icon

- 順便記一下數莓派的IP


變更驗證方式(就是這一步導致mac出現版本不相容問題)

- 點擊視窗中右上角選單的Option,在security選項中將Authentication改成VNC password

- 預設為UNIX password,但在mac上會出現版本不符無法連線的問題



回到Mac中的finder,前往> 連接伺服器

-vnc://[數莓派IP位置]


就可以遠端連到數莓派畫面了


若數莓派桌面未顯示VNC 圖示,則需要先安裝VNC Viewer

啟動VNC

-sudo raspi-config > interface 啟動vnc server

安裝vnc server

-sudo apt-get install realvnc-vnc-server

設定VNC密碼

-sudo vncpasswd -service

設定VNC驗證方式

-sudo nano /etc/vnc/config.d/common.custom

-加入 Authentication=VncAuth (ctrl X 存檔離開)

重新啟動服務

-sudo systemctl restart vncserver-x11-serviced


* 另外一個方式是 從Mac下載realVNC Client,安裝完畢後就可以透過VNC Client 連線了

2020年10月15日 星期四

Ubuntu 18.04 使用php ssmtp發送信件,以gamil為例

前置作業
- 確認環境的Port有開通,例如: 25、465、587是通的

安裝ssmtp 
sudo apt-get install ssmtp

設定sstmp config
sudo vi /etc/ssmtp/ssmtp.conf

修改如下設定
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
# 設定要用的轉寄信箱
root=[例:test@gmail.com]
# The place where the mail goes. The actual machine name is required no 
# MX records are consulted. Commonly mailhosts are named mail.domain.com
# 信箱SMTP位置
mailhub=[例:smtp.gmail.com:587]
#輸入以下登入驗證帳號/密碼
AuthUser=[例:sender@gmail.com]
AuthPass=[例:test@password]
#根據轉寄信規則選擇是否使用TLS、SSL
UseTLS=YES
UseSTARTTLS=NO
# Where will the mail seem to come from?
#輸入信箱網域名稱
rewriteDomain=[例:gmail.com]
# The full hostname
#主機名稱
hostname=[主機名稱]
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES

新增php測試mail程式testmail.php
sudo vi /var/www/html/testmail.php

新增以下程式碼
<?php
$to="[例:test@mail.com]";
$subject="[例:這是主旨]";
$msg="[例:這是內文]";
$headers="From: [例:sender@gmail.com]";
if(mail("$to","$subject", "$msg", "$headers"))
        echo "send";
else
        echo "fail";
?>

測試
-到瀏覽器輸入[主機位置]/testmail.php,測試php程式;應該就會在php程式中to=的信箱收到信件

可查看寄送的mail log,判斷是否有問題;有可能因為驗證錯誤或網路問題而導致沒收到信
sudo tail /var/log/mail.log

(以上是在php7.2版本執行,不太確定是否其他版本還有其他需要的設定)

2020年9月24日 星期四

Ubuntu 18.04. 安裝php7.2, mysql


安裝php:

sudo apt update

安裝php相關套件:

sudo apt install php php-cli php-fpm php-json php-pdo php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath

查看php版本:

php -v

Ubuntu18.04的php會預設為php7.2版本。


安裝mysql

sudo apt install mysql-server 

sudo apt install mariadb-server-10.0 (安裝在數莓派上要用這個)

安裝後預設密碼空白,需要修改mysql root 密碼

sudo mysql -uroot -p 

進入mysql後輸入以下指令來設定root帳號密碼

mysql>UPDATE mysql.user SET authentication_string=PASSWORD('[密碼]'), plugin='mysql_native_password' WHERE User='root' AND Host='localhost';

>flush privileges;


變更密碼指令:

SET PASSWORD FOR '[帳號]'@'localhost' = PASSWORD('[密碼]');


修改mySQL設定
- 預設MySQL是只允許本機存取,因此要修改成允許遠端存取
-  sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
-  將blind-address這一行的IP改成自己要遠端的IP,若不限制可以加上#註解掉
-在[mysqld]區塊中加上character-set-server=utf8 

啟動mySQL
-輸入指令:sudo systemctl start mysql
- 查看運作狀況service mysql status


安裝phpmyadmin

sudo apt install phpmyadmin

php7.2以後的phpmyadmin有些問題,因此都會出現錯誤訊息;小弟尚未查到完整修改的方式,

但因為不引響實際網站存取資料庫問題,因此就先不管了。

若朋友有解法分享,小弟萬分感謝。

設定phpmyadmin連結網址:

sudo ln -s /usr/share/phpmyadmin /var/www/html/[例:phpmyadmin]


設定mysql使用者允許遠端連線(視需求設定)

若mysql在遠端環境,則需要允許遠端連線,可將以下指令IP改為%,或指定特定IP,若為本機用戶則輸入localhost。

允許遠端連線帳號權限,進入mysql後

mysql>GRANT ALL PRIVILEGES ON *.* TO '[帳號]'@'IP' IDENTIFIED BY '[密碼]';

更新權限

mysql>flush privileges;


PS. 若是由程式讀取本機資料庫,使用者可設定為Localhost,程式端的資料庫位置也要localhost才行。


2020年8月6日 星期四

JQuery ajax post, php接收,回傳資料

花了些時間研究圖片上傳功能。
前端將圖片轉成Base64後,透過ajax post傳到後端php程式,由程式寫入資料庫並產生圖片路徑,再回傳圖片路徑資料給前端。

前端程式:
Head設定語系跟載入jquery
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
</head>

HTML:包含一個編號、一個選擇圖片功能,一個上傳按鈕,還有一個顯示回傳資料的欄位
<html>
    <form>
        <label> 編號
            <input id="pid" type="text"/>
        </label>
        <label> 圖檔:</label>
        <label class="btn_img">請選擇圖片
            <input id="upload_img" type="file">
        </label>
        <div class="edit_form_img">
            <img id="img_preview" />
        </div>
        <input id="sent" class="form_submit" type="button" value="submit" ></input>
    </form>
    <label id="info"></label>
</html>

JS:將選擇的圖片轉成base64並產生預覽
    $("#upload_img").change(function() {
        //readURL(this);//互叫變更預覽圖片的功能
        //取得file選擇的檔案
        pv_img = $("#upload_img").get(0).files[0];
        //新增reader物件轉成base64資料,再onload時寫入圖片的scr
        var reader = new FileReader();
        reader.onload=function(){
            $("#img_preview").attr('src',reader.result);
        }
        reader.readAsDataURL(pv_img);
    });

JS 當上傳按鈕被點擊後,取得資料,並透過ajax Post到php
-這裡偷懶取代base64資料前的資料描述文字,但比較好的作法應該是要另外存檔案格式,之後轉回圖片時再加上附檔名(這動作可以在php端處理,也可以在前端)
-processData這個參數有點神奇,當true時data參數才能正確傳到php端,false就不行了;但網路上有些範例卻說要用false。若有大大知道原理,還忘不吝告知,感恩喔!
-data的傳送方式試過傳送form序列化或json.stringfy,但資料還是送不出去;這邊提供傳送成功的方式跟php接收的程式有關係。
- 取回php回傳的陣列資料,先抓兩個欄位顯示出來。

    $('#sent').click(function(){
        img64=$("#img_preview").attr("src");
        sb64=img64;
        //取代編碼後前面的描述文字
        sb64= sb64.replace("data:image/jpeg;base64,",''); 
        $.ajax({
            url:'jsonPHP.php',
            type: 'POST',
            processData: true, //false時,data參數無法傳到php POST接收端,true時才可以
            dataType: "json",
            //傳送data參數值
            data: { 'pid':$("#pid").val(),     
                    'sb64':sb64
                },
            success: function(data){
                console.log(data);
                //取回php回傳的陣列資料
                    var imgsNum=data.length;
                    for (i=0;i<imgsNum;i++){
                        imgid=data[i]['img_id'];
                        imgurl=data[i]['img_url'];
                        $("#info").append("id:"+imgid+"|url:"+imgurl);
                    }
                },
        });  
    });

PHP程式
- 取得前端傳遞的資料後,呼叫寫入資料的程式,再透過查詢回傳同個編號的圖片資料
- Insert_img 先將base64資料轉成圖片,我去抓一個時間當作檔名(這是另外引入的函式),再將資料存到資料庫
- query_img查詢同個ID的資料,存成陣列後回傳。


<?php
    header('Content-Type: application/json; charset=UTF-8');
    require_once("fundation_func.php");
    $link = new mysqli($dbhost,$dbuser,$dbpass,$db);

    //偵測POST的資料與前端ajax參數有關,要對應才行
    if ($_SERVER['REQUEST_METHOD'] == "POST"){
        @$id=$_POST["pid"];
        //@$name=$_POST["name"];
        @$sb64=$_POST["sb64"];
        $msg="取得pid:".$id;
        echo json_encode(insert_img($link, $id,$sb64));
    }else
    {
        $msg="request錯誤";
        echo json_encode(array(
            'msg'=> $msg
        ));
    }

    function insert_img($link,$product_id,$sb64){
        //產生圖片路徑
        $img_file=base64_decode($sb64);
        $file_name=get_pure_text(get_file_no());
        $file_url="product_imgs/".$product_id."_".$file_name.".jpg";
        file_put_contents($file_url, $img_file);

        //新增產品圖片資料的SQL
            $sql="INSERT INTO product_img(product_id, imgb, img_url) VALUES ('$product_id','$sb64','$file_url')";
            $link->query($sql);
        //查詢產品圖片
        return query_img($link,$product_id);
    }

//查詢同個ID的圖片函式,會回傳一個陣列
    function query_img($link,$product_id){
        $imgs_array=array(
            array('img_id','img_url'),
        );
        $sql="SELECT img_id, img_url FROM product_img WHERE product_id=$product_id";
        $result=$link->query($sql);
            $i=0;
            while($row=$result->fetch_array(MYSQLI_ASSOC)){
                //將查到的產品圖片存到array中
                $imgs_array[$i]=array(
                        'msg'=>"ss",
                        'img_id'=>$row['img_id'],
                        'img_url'=>$row['img_url']
                );
                $i++;
            }
            return $imgs_array;
    }
?>



2020年7月29日 星期三

JQuery/PHP 顯示上傳的圖片、取得php檔案路徑、隱藏圖片區塊、刪除圖片檔案

上傳圖片的功能與三種情境有關,整理作法如下:
1、 該頁面上無圖片,則隱藏圖片區塊,再上傳圖片後顯示預覽
2、該頁面已有圖片,則取得圖片路徑並顯示出來
3、刪除圖片後,隱藏圖片區塊

html:包含一個圖片區塊、一個上傳功能、一張圖片、一個刪除按鈕
<div class="img_col">
    <input id="upload" type="file" name="myfile">
    <img id="img_view" />
    <lable id="btn_del" class="btn_del" >刪除</label>           
</div>


JS:載入頁面時取得php的圖片路徑,若有則顯示圖片,若沒有則隱藏圖片區塊
<script>
    //當網頁載入時
    $(document).ready(function(){ 
        // 將php參數img_url指派給 JS 變數 img_view
        var img_view="<?php echo "$img_url" ?>";
        
        //當img_view有資料-> 圖片資料存在>顯示圖片、反之>隱藏區塊
        if (img_view){
            //以JQuery變更#img_view圖片的SRC參數為img_view
            $("#img_view").attr('src', img_view);
            //以JQuery指定刪除功能按鈕的Click事件,呼叫刪除圖片的函式(見後)
            $("#btn_del").click(function(e){
                del_img(img_view);
            });
        }else{
            //隱藏圖片區塊,及刪除功能按鈕
            $(".img_col").hide();
            $("#btn_del").hide();
        }
    });
</script>


JS:選擇圖片後,將圖片顯示為所選擇的圖 (參考來源資料)
<script>//選擇圖片後產生預覽
    //當input file的的upload變更時,呼叫readURL函式
    $("#upload").change(function() {
            readURL(this);

    function readURL(input) {
        //有可能圖片區塊這時被隱藏,因此先讓區塊顯示出來
        $(".edit_form_img").show();
        $("#btn_del").show();

        if (input.files && input.files[0]) {
            var reader = new FileReader();
                    
            reader.onload = function(e) {
                $('#img_preview').attr('src', e.target.result);
            }
               reader.readAsDataURL(input.files[0]); // convert to base64 string
            }
        }
    });
</script>


JS:刪除圖片函式
function del_img(img)//確認刪除圖片後,刪除圖片
    {
        if (confirm("確認刪除照片?"))
        //這邊將刪除寫在另一支php程式,並取得圖片路徑後將檔案刪除
        location.href="del_product_img.php?img="+img;
    }

PHP:刪除圖片php程式
- 資料庫連線部分就不寫了
- SQL將圖片的欄位update為空值
- 刪除圖片檔案


<?php 
    //取得傳入要刪除的圖片路徑
    $img_url=$_GET["img"];

    //將取得的檔案路徑 update為空值的SQL
    $img_del="UPDATE product set product_img=''  WHERE product_img='$img_url'";

    // 執行SQL (這段的$link是物件>$link = new mysqli($dbhost,$dbuser,$dbpass,$db))
    $result=$link->query($img_del);

    //將檔案自系統中刪除
    unlink($img_url);//將圖片檔案刪除
    
    //刪除後轉址到原頁面
    header("location:o_page.php");
?>



2020年7月28日 星期二

JQuery 滑動checkbox(Switch開關)寫入表單

使用JQuery做一個啟用、停用的切換switch,並將參數傳到表單中;
範例如下:

第一段JS:判斷PHP取自資料庫的參數,並呈現目前的狀態

<script>//檢查產品發佈狀態,顯示對應的publish狀態
        $(document).ready(function(){
           var publish=<?php echo"$is_publish" ?>;
           if (publish==0){
              $("#publish").prop("checked",'');
           }else{
              $("#publish").prop("checked",true);
           }
        });
</script>

HTML:表單中CheckBox的部分
- 由CSS去控制Checkbox樣式,讓他顯示成一個Switch開關
- 實際上是一個Chcekbox判斷是否有勾選
- 用onchange參數呼叫JS來寫入整個表單要傳給另一支php的參數
<!--Switch開關顯示html的部分-->
<label class="col_title">是否發布</lable>
<label class="switch">
    <input id="publish" type="checkbox" name="publish" onchange="check_publish()" >
    <span class="slider round"></span>
</label>


CSS:顯示如Switch開關的CSS
.switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 34px;
  }
  
  /* Hide default HTML checkbox */
  .switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }
  
  /* The slider */
  .slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  .slider:before {
    position: absolute;
    content: "";
    height: 26px;
    width: 26px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
  }
  
  input:checked + .slider {
    background-color: #2196F3;
  }
  
  input:focus + .slider {
    box-shadow: 0 0 1px #2196F3;
  }
  
  input:checked + .slider:before {
    -webkit-transform: translateX(26px);
    -ms-transform: translateX(26px);
    transform: translateX(26px);
  }
  
  /* Rounded sliders */
  .slider.round {
    border-radius: 34px;
  }
  
  .slider.round:before {
    border-radius: 50%;
  }



第二段JS:根據checkbox狀態,寫入要傳到表單的值(非必要)
*checkbox勾選時預設value為on,否則就是空值
*因此接收表單的程式只要判斷有沒有回傳值,再寫入對應的資料即可
-以下是變更on為a,若後端要特定數值可參考

<script>
//檢查發布CheckBox是否被勾選,寫入特定值
        function check_publish(){  
            if($("#publish").is(':checked'))
                $("#publish").val('a');
        }
 </script>


2020年7月13日 星期一

mysqli::query(): Couldn't fetch mysqli 問題排除紀錄

發生了幾次mysqli::query(): Couldn't fetch mysqli 的錯誤,
紀錄解決方式如下:

原因一: SQL語法有錯
- 將查詢語法輸出,再把輸出的SQL放到mysql中執行看看結果是否正確
- 發生了where欄位條件='xxx' 沒加上'',int的時候不用''


原因二: 太早結束連線時,導致接續的查詢出錯
- 先查詢資料重複再插入新資料時,若在查詢重複資料時就結束連線,就會出現錯誤。

$sql->query(查詢)
$sql->close()  //這時就會出錯,移除這一個步驟的Close()就可以排除問題

$sql->query(插入資料)
$sql->close()

用JS語法檢查email格式


//JS 正規表示式
emailRule = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
//取得email欄位值並檢查規則,不符規則會回傳-1
if(document.form.email.value.search(emailRule)==-1 ){
alert("信箱格式有誤");  
}else{
 form.submit();
}            



mysql, php取得特定字串

透過mysql語法取得欄位中的部分字串:

左邊取得特定[文字長度]
SELECT [欄位名], LEFT([欄位名] ,[文字長度]) FROM [資料表] WHERE [條件]
例: SELECT content, LEFT(content,50) FROM contacts 

從右取得特定[文字長度]
SELECT [欄位名], RIGHT([欄位名] ,[文字長度]) FROM [資料表] WHERE [條件]
例: SELECT content, LEFT(content,50) FROM contacts 

透過php語法取得欄位中的部分字串:
mb_substr([字串], [起始位置], [取得長度], [編碼])
例: 
$str="abcd甲乙丙0987654321";
$sub=mb_substr($str, 2, 5, "utf8");
echo "sub=$sub";

輸出結果: sub=cd甲乙丙

2020年7月9日 星期四

PHP 更新ubuntu PHP版本

更新PHP版本從7.0~ 7.4

在php7.4的環境開發,放到php 7.0的環境後發現有些程式碼有問題,
所以只好進行更新到新版本。

直接更新
指令:sudo apt upgrade php
(會安裝中間的各個版本)

若只要安裝php 7.4
指令:sudo apt-get install php7.4

接著要安裝新版模組
指令:sudo apt install php7.4-curl  php7.4-mbstring php7.4-zip php7.4-mysql
(根據需求安裝會用到的模組)

安裝後需要停用舊版本
指令:a2dismod php7.0

接著啟用新版本php
指令:a2enmod php7.4

重新啟用apache
指令:sudo service apache2 restart

確認apache 服務狀態
指令:sudo service apache2 status
如下就是啟用了


若有需要可以在網站目錄(預設/var/www/html/),
增加info.php再輸入網址來顯示php資訊。
php程式碼:
<?php
phpinfo();
?>




2020年7月1日 星期三

PHP- 編碼後html還原 "htmlspecialchars_decode",轉換為純文字

為了避免SQL 注入將寫入的資料進行編碼,但對於文字編輯器所寫入的資料還是要有辦法還原回來。

經過編碼寫入DB的資料如下:
看到&amp;nbsp;&lt;span style=&quot;color: #ff6600;&quot;&gt;&lt;strong&gt;AJA System Test&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;的讀寫效能分別為&amp;nbsp;&lt;span style=&quot;color: #0000ff;&quot;&gt;&lt;strong&gt;1485/1022 MB/s&lt;/strong&gt;&lt;/span&gt;(寫入/讀取),另外在&amp;nbsp;&lt;span style=&quot;color: #ff6600;&quot;&gt;&lt;strong&gt;Blackmagicdesign&lt;/strong&gt;&lt;/span&gt;&amp;nbsp;的讀寫效能則分別為&amp;nbsp;&lt;strong&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1311.7/1302.6 MB/s&lt;/span&gt;&lt;/strong&gt;(寫入/讀取),內建的硬碟則可完整支援各種檔案格式,雖然讀寫效能沒有 MacBook Pro 內建硬碟來得出色,但整體來說還是相當不錯的表現。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img class=&quot;lazy loaded&quot; src=&quot;https://attach.mobile01.com/attach/202006/mobile01-20e81a590fecb2cd05d3321bf5150e84.png&quot; data-src=&quot;//attach.mobile01.com/attach/202006/mobile01-20e81a590fecb2cd05d3321bf5150e84.png&quot; data-was-processed=&quot;true&quot; /&gt;&lt;br /&gt;MacBook Air 2020!&lt;br /&gt;&lt;br /&gt;&lt;img class=&quot;lazy loaded&quot; src=&quot;https://attach.mobile01.com/attach/202006/mobile01-b8de9b28a0927c218e3df159d72e41e7.jpg&quot; data-src=&quot;//attach.mobile01.com/attach/202006/mobile01-b8de9b28a0927c218e3df159d72e41e7.jpg&quot; data-was-processed=&quot;true&quot; /&gt;&lt;br /&gt;其實這幾年小編因為工作需要的關係,加上已經習慣大尺寸的顯示螢幕,小編就選擇犧牲行動性選擇效能更佳的 MacBook Pro 16 作為主要的行動工作筆電。這次再度重返 MacBook Air 的懷抱,最讓小編開心的就是肩膀的重量減輕了...&lt;img class=&quot;lazy loaded&quot; title=&quot;XD&quot; src=&quot;https://attach2.mobile01.com/images/emotions/dark/7.gif&quot; data-src=&quot;//attach2.mobile01.com/images/emotions/dark/7.gif&quot; data-was-processed=&quot;true&quot; /&gt;。

還原成html格式
可使用htmlspecialchars_decode($inputtext)



轉換為純文字
可能因為還原導致出現空格,因此要去除前後及中間的空格,
去掉html標籤,並取代特殊符號。

例如:
$str=trim(strip_tags($str));// 去除html標籤及前後空格
$puretext = preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", "",$str); //去除特殊符號及內文中的空白

最後得到的$pretext就是純文字了

2020年6月14日 星期日

PHP- 預防SQL injection 字串處理"htmlentities"、"stripslashes"、"real_escape_string"

要避免網頁輸入欄位的SQL injection,基本的方式是針對輸入欄位、POST、GET..
等數值進行處理。

htmlentities():去除字串中的html標籤
stripslashes():讓文字及符號呈現原始輸入的文字,不受html語法影響
real_escape_string():轉換特殊符號

可參考以下範例試試看:
<html>
<form action="trail_string_clear.php" method="post" name="textform">
原始輸入<br>
<textarea id="editor1" name="inputtext" type="textarea" style="width:400px;height:200px;"></textarea><br>
<input class="form_submit" type="Submit" value="Submit"></input>
</form>


</html>

<?php
require_once("fundation_func.php");
$link = new mysqli($dbhost,$dbuser,$dbpass,$db);
$inputtext=$_POST['inputtext'];
$stripslashes=htmlentities($inputtext);
$htmlentities=stripslashes($inputtext);
$real_escape_string=$link->real_escape_string($inputtext);
echo "<font color='black'>未處理字串:$inputtext<br></font>";
echo "<font color='blue'>stripslashes處理後:$stripslashes<br></font>";
echo "<font color='red'>htmlentities處理後:$htmlentities<br></font>";
echo "<font color='green'>real_escape_string處理後:$real_escape_string<br></font>";
?>



輸出畫面:


輸入的字串





PHP 在MAC中 move_upload_file 無法移動檔案到目錄的問題

使用upload_file上傳檔案存在暫存區後,要移動到指定路徑並變更檔名失敗;

原因是MAC 目錄權限問題,使用以下指令就可以成功將檔案存到路徑中了。

sudo chmod 777 [目錄路徑]


重啟服務

sudo apachectl restart


2020年6月10日 星期三

PHP 連線資料庫的兩種方法(mysqli_connect、new mysqli物件)

以下兩種連線資料庫的方法,(一)mysqli_connect跟 (二)使用mysqli物件:

資料庫連線基本資訊
$dbhost='[IP位置/Localhost]:[3306/Port號]';
$dbuser='[資料庫帳號]';
$dbpass='[資料庫密碼]';
$db='[資料庫名稱]';


方法一:mysqli_connect
// 1) 建立連線
$link=mysqli_connect($dbhost,$dbuser,$dbpass,$db);//建立連線
if(! $link) {
    die ('Connect Fail:'. mysqli_error($link));
}
echo 'Connect Sueccess';

//2) 查詢資料
$sql_query="SELECT * FROM table"; //查詢指令
$query=mysqli_query($link, $sql_query); //執行查詢,並將查詢結果存在$query中
while($row=mysqli_fetch_array($query,MYSQLI_ASSOC))//將查詢結果存到$row陣列中
    {
        echo"$row['欄位名稱']";//這邊就看查詢的資料有什麼欄位
    }

//3) 結束資料庫連線
mysqli_free_result($query);//釋放記憶體
mysqli_close($link);//結束連線


方法二:mysqli_connect
// 1) 建立連線
$link= new mysqli($dbhost,$dbuser,$dbpass,$db);//建立物件並連線資料庫
if($link->connect_error) {
    die ('Connect Fail:'. mysqli_error($link));
}
echo 'Connect Sueccess';

//2) 查詢資料
$sql_query="SELECT * FROM table"; //查詢指令
$query=$link->query($sql_query);//執行查詢,並將查詢結果存在$query中
while($row=mysqli_fetch_array($query,MYSQLI_ASSOC))//將查詢結果存到$row陣列中
    {
        echo"$row['欄位名稱']";//這邊就看查詢的資料有什麼欄位
    }

//3) 結束資料庫連線
    $query->free();//釋放記憶體
    $link->close();結束連線




PHP parse_ini_file() 範例

使用ini檔案儲存環境設定資料,再以parse_ini_file()取得環境設定值。

web.ini檔案
[config]
dbhost='111.111.111.111:3306';
dbuser='Alice';
dbpass='Aloceloveu';
db='ff7';

php檔案
<?php
$ini = parse_ini_file('webconfig.ini',true);// 取得資料庫設定
    $db=$ini["config"]["db"];
    $dbhost=$ini["config"]["dbhost"];
    $dbuser=$ini["config"]["dbuser"];
    $dbpass=$ini["config"]["dbpass"];

echo "db=$db <br>host=$dbhost<br>user=$dbuser<br>pass=$dbpass";
?>

結果
db=ff7
host=111.111.111.111:3306
user=Alice
pass=Aloceloveu



2020年6月2日 星期二

從MAC使用gcloud SDK傳輸檔案到GCP

為了建立在PC、MAC上都可以連到GCP測試站的開發環境;但若用GCP console的檔案傳輸需要透過Bucket或單個檔案上傳,實在有點麻煩。
所以就試著用gcloud SDK以終端機command line的方式來上傳檔案 。


安裝GCP套件需要安裝Python
-MAC中預設的是python2.7,而GCP套件目前可支援Python2.7,但未來會只支援Python3以上版本,所以就來研究一下怎麼安裝Python3囉。


開啟終端機進行Python3安裝
1) 要先安裝Brew,輸入以下指令
-ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2) 安裝Python3,輸入以下指令
-brew install python3


安裝GCP的套件
- 下載的檔案解壓縮後,放到想要的目錄中
- 在終端機中輸入 [目錄名稱]/google-cloud-sdk/install.sh
- 會問題要不要回報問題給GCP及重新設定路徑,可以選擇不輸入就略過
- 最後重新開啟終端機


安裝GCP SDK,在終端機中輸入以下指令
gcloud init
- 會開始在本機建立一個預設設定檔(default configuration)
- 接著會要求你登入Google帳號
- 會詢問要選擇哪個在GCP建立的專案,或新建專案
- 詢問要不要變更區域資料
- 設定後就安裝完成了

設定GCP專案中繼資料的區域資訊

設定專案中的中繼資料,需要設region=[選擇的區域]及-zone=[選擇的區域]

gcloud compute project-info add-metadata --metadata google-compute-default-region=asia-east1,google-compute-default-zone=asia-east1-b


設定Client預設設定檔中的區域資訊
再來要設定Client端社區域資訊,這樣使用指令時才不用每次都要輸入

gcloud config set compute/zone asia-east1-b

gcloud config set compute/region asia-east1


連線GCP VM,在終端機輸入以下指令
gcloud compute ssh [Instance_name]
- 輸入passphrase後,就會產生SSH public key跟Private Key並存在電腦中
- 之後就可以從終端機輸入gcloud compute ssh [Instance_name] 連線到GCP的VM了

設定SSH 中繼資料
- 產生後的SSH Key會存在 預設路徑user/[使用者名稱]/.ssh/
- 目錄中會有兩個檔案*.pub是public key, 另一個沒有副檔名的是private key 
- 將public key用文字檔打開並複製
- 進入GCP console compute engine > 中繼資料 > 安全殼層金鑰
- 新增,然後將複製的public Key貼上後儲存 
- 這樣用完成SSH的設定了
- 這個Key就會是root帳號的Key,以下傳輸檔案時就可以帶root作為帳號來進行操作


傳輸檔案
先確認目前終端機是在本地不是連到VM上 (輸入指令回傳找不到目錄好幾次,才發現原來已經SSH連到VM了.. Orz)

整個目錄上傳指令: gcloud compute scp --recurse [本地目錄] [帳號]@[VM_名稱]:[VM目錄]
- 在輸入兩次passphrase,就會開始上傳了。
* 在前面的SSH Key設定中沒有帳號,這個步驟可以帶root;回到GCP console中的中繼資料中看,會多一個root的金鑰

- 單一檔案上傳指令: gcloud compute scp [本地目錄] [帳號]@[VM_名稱]:[VM目錄]


GCP連線相關問題

ERROR: (gcloud.compute.scp) Could not fetch resource:

 - Insufficient Permission: Request had insufficient authentication scopes.

需要重新驗證身份
指令-sudo gcloud auth login
輸入後再重新登入Google 帳號就可以了

ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255]

專案可能有instance或區域重新設定:需要更新SSH 金鑰
指令-sudo gcloud compute config-ssh
出現這問題時,不一定靠更新SSH可以排除... 還需研究






Ubuntu 安裝php、mysql、phpmysdmin

記錄常用的Ubuntu安裝動作,
將安裝php、mySQL、phpmyadmin

安裝PHP、Apache
sudo apt-get update
sudo apt-get install apache2 php libapache2-mod-php
安裝後網站路徑為/var/www/html/

修改php.ini設定
設定檔路徑:
sudo vi /etc/php/7.0/apache2/php.ini

extension設定

-extension=php_mbstring.dll

-extension=php_mysqli.dll
檔案上傳設定
-upload_file_maxsize=20MB
-upload_max_filesize = 20M
開發時錯誤顯示,避免發生錯誤時只顯示空白畫面
-display_errors=On

安裝mySQL
$ sudo apt-get install mysql-server
//$ sudo apt-get install mysql-client
//以下為資安考量安裝可省略
//$mysql_secure_installation 
- 會開始設定root的密碼,以及密碼安全性的檢核程度;建議根據已設定密碼的強度來選擇
- 選擇是否要允許遠端;視情況囉
- 選擇是否要移除測試資料庫;建議移除
- 確認重新載入權限表

修改mySQL設定
- 預設MySQL是只允許本機存取,因此要修改成允許遠端存取
-  sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
-  將blind-address這一行的IP改成自己要遠端的IP,若不限制可以加上#註解掉
-在[mysqld]區塊中加上character-set-server=utf8 

設定mySQL root密碼
- 預設mySQL root 密碼為空白需變更,
-sudo mysql -uroot -p
- 進入mysql開始變更root帳號密碼
- >UPDATE mysql.user SET authentication_string=PASSWORD('[密碼]'), plugin='mysql_native_password' WHERE User='root' AND Host='localhost';
- >flush privileges;
- exit;


啟動mySQL
-輸入指令:sudo systemctl start mysql
- 查看運作狀況service mysql status

安裝php-MySQL套件
- 輸入指令:sudo apt install php-mysql

安裝phpMyAdmin
$ sudo apt-get install phpmyadmin
//$ sudo apt-get install php-mbstring

//$ sudo apt-get install php-gettext
- 安裝後會出現設定phpmyadmin的密碼

phpmyadmin設定
設定檔路徑
$sudo vi /etc/dbconfig-common/phpmyadmin.conf
dbc_dbuser='[帳號]'
dbc_dbpass='[密碼]'


在www中設定連結
$ sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

啟動apache
- 輸入指令:sudo apachectl start
*如有變更php.ini或mysql設定,需要重新啟動 sudo apachectl restart

測試:
1) php執行: 輸入 [localhost/ip]/
2) phpmyadmin: [localhost/ip]/phpmyadmin
3) 檢查mySQL語系設定,確認是否有非UTF8的語系 
-show variables where Variable_name like '%character_set%'
utf8mb4 兼容UTF8