2021年3月18日 星期四

PHP 處理一般文字檔案

設定目標:
  • 了解 PHP 處理一般文字檔案的概念與方法

PHP 處理檔案概念
  1. 權限認知
    • PHP 引擎需要有對應的系統權限,才可以對系統本身的檔案目錄進行存取!
    • PHP 如果是在 web server 上運作,其使用的權限就只是運作 web server 使用者的權限!
    • PHP 可否讀寫系統的檔案,視系統付予 PHP 使用者多大的可用權限!
PHP 處理檔案實際操作
  1. 讀檔
    • 範例: readfile.html
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>{titlename}</title>
      </head>
      <body bgcolor="{color}">
      <h1>Hello, {name}</h1>
      </body>
      </html>
    • 範例:readfile.php
      <?php
      $page = file_get_contents('readfile.html');
      
      $page = str_replace('{titlename}', 'Welcome', $page);
      
      if (date('H') >= 12)){
          $page = str_replace('{color}','blue',$page);
      } else {
          $page = str_replace('{color}','red',$page);
      }
      
      $page = str_replace('{name}', 'Kitty', $page);
      
      print $page;
      ?>
      
  2. 寫檔
    • writefile.php
      <?php
      $page = file_get_content('readfile.html');
      
      $page = str_replace('{titlename}','HelloWorld',$page);
      
      if (date('H' >= 12)) {
      	$page = str_replace('{color}','blue',$page);
      } else {
          $page = str_replace('{color}','green',$page);
      }
      
      $page = str_replace('{name}',$_SESSION['name'],$page);
      
      file_put_contents('writefile.html', $page);
      
      ?>
      
  3. 讀寫部份檔案:
    • 使用 file() 函數,一行一行讀取需要的內容!
    • 範例:email.txt
      apple@example.com|apple mac os
      microsoft@example.com|bill gates
      aws@example.com|bruce fu
      
    • reademail.php
      <?php
      foreach (file('email.txt') as $line){
          $line = trim($line);
          $info = explode('|', $line);
          print '<li><a href="mailto:' . $info[0] . '">' . $info[1] ."</a></li>\n';
      }
      ?>
      
    • 使用 fopen()函數:一次只讀取一行,節省記憶體空間的浪費!
    • freademail.php
      <?php
      $fh = fopen('email.txt'),'rb');
      while ((! feof($fh)) && ($line = fgets($fh))){
          $line = trim($line);
          $info = explode('|', $line);
          print '<li><a href="mailto:' . $info[0] . '">' . $info[1] ."</a></li>\n';
      }
      fclose($fh);
      ?>
      
    • 使用 fwrite() 函數,將資料寫回檔案內!
    • fwritemail.php
      <?php
      $fh = fopen('email.txt'),'wb');
      fwrite($fh,"james@example.com|lebron james\n");
      fclose($fh);
      ?>
      

2021年3月14日 星期日

2021 海外青年專班專題目錄

宗旨目的:
  • 記錄專班學員學習成長歷程

2021 海外青年專班 Github 連結列表
  1. 李沃利
  2. 林觀生
  3. 林清豪
  4. 莊槿鴻
  5. 德來
  6. 許立安
  7. 李政興

PHP 錯誤與例外處理

設定目標:
  • 了解 PHP 錯誤與例外發生時的處理方式

PHP 處理錯誤與例外發生的方式
  1. 掌握錯誤與例外
    • 避免非預期的結果干擾使用者!
    • 強化安全性,避免惡意的使用者查覺系統問題!
    • 在預期錯誤發生時,仍可導入正常處理流程!
  2. 錯誤的情況處理分類
    • die 況狀 : 利用 die() 函數處理錯誤情形,將程式導出並且中止執行!
    • 客製化錯誤 : 發生錯誤情形時,導入自製的處理程序!
    • 錯誤報告 : 將錯誤情形報告出來,寫入檔案或是資料庫!此種報告可協助找出錯誤問題,加以處理!
    • 例 : 自行客製化錯誤的方式 myError.php
      <?php
      function my_error_handler($error_no, $error_msg) {
        echo "Opps, something went wrong:";
        echo "Error number: [$error_no]";
        echo "Error Description: [$error_msg]";
      }
      set_error_handler("my_error_handler");
      echo (5 / 0);
      ?>
      
  3. 錯誤與例外的不同
    • 例外是可以抛出與接收處理,但錯誤則是無法恢復!
    • 例外可以使用物件導向的方式來掌握與處理!
  4. 例外的情況處理分類
    • 注意(Notice): 不嚴重的問題,程式也不會停止
    • 警告(Warning): 程式碼有錯誤,但程式亦不會停止執行
    • 致命錯誤 (Fata Error): 遇上嚴重錯誤,程式停止執行
  5. try…catch 敘述
    • 語法
      try {
        可能會發生錯誤的程式碼;
      } catch(Exception $e){
        處理例外的程式碼;
      }
      
    • Exception 是 PHP 處理例外的類別
      • 屬性值有兩個,一個是訊息,另一個則是代號值
      • 訊息會描述程式產生錯誤的地方
      • 代號值為錯誤代碼
      • 使用的語法 : 可以自行抛出 Exception
        throw new Exception('Error Message', 100);
        
  6. 抛出例外與接收
    • 當程式抛出例外時,程式會自動暫停,接下來的程式碼也不會運作!
    • 例 : throwExp.php
      <?php
      function check($num){
        if ( $num == 0 ){
          throw new Exception('num can not be 0', 100);
        }
        return $num;
      }
      
      try{
        echo check(0);
      } catch (Exception $e){
        echo "Error Message: ".$e->getMessage()."
      "; echo "Error Code: ".$e->getCode()."
      "; } ?>
  7. Exception 類別的繼承
    • 利用繼承 Exception 類別,自訂例外處理的屬性與方法!
    • 例 : selfExp.php
      <?php
      class EmailFormatException extends Exception {
        function printMessage(){
          echo "例外訊息:" . $this->getMessage() . "
      "; } } function checkEmail($email){ if (!strpos($email,"@")) throw new EmailFormatException("E-mail需要包含'@'"); } try { checkEmail('gmail.com'); } catch (EmailFormatException $e){ $e->printMessage(); } ?>
  8. 多層次的例外處理
    • 執行程式時,可能會發生多種情況的例外,可以寫多個 catch 來補抓例外!
    • 例 : multiCatchExp.php
      <?php
      class DivideByZeroException extends Exception {};
      class DivideByNegativeException extends Exception {};
      function process($denominator) {
        try    {
          if ($denominator == 0) {
            throw new DivideByZeroException();
          }    else if ($denominator < 0) {
            throw new DivideByNegativeException();
          }    else {
            echo 25 / $denominator;
          }
        }    catch (DivideByZeroException $ex)    {
          echo "DIVIDE BY ZERO EXCEPTION!";
        }    catch (DivideByNegativeException $ex)    {
          echo "DIVIDE BY NEGATIVE NUMBER EXCEPTION!";
        }    catch (Exception $x) {
          echo "UNKNOWN EXCEPTION!";
        }
      }
      process(0);
      ?>
      

本章練習:
  • 修改你的 dog、cat、Human 類別,別讓它被餵食錯誤的飼料,例如:Human 不可以吃 cat 罐頭!

PHP 的 Trait 用法

設定目標:
  • 了解 PHP 如何使用 Trait 來解決跨類別問題

Trait 概念與實作
  1. 特徵(Trait)
    • Trait 與抽象類別相似,無法使用 new 來產生物件(被實例化)!
    • 因為 PHP 只能單一繼承,所以無法跨多個類別使用這些類別內的方法!
    • 為了減少程式碼的重複撰寫,所以 PHP 使用 Trait 來克服這個問題!
    • 使用 Trait 可以讓 PHP 實現單一類別(Singleton)的使用!
    • 單一 Trait 使用範例 :
      • oneTrait.php
        <?php
        class Base {
          public function sayHello() {
            echo 'Hello ';
          }
        }
        trait SayWorld {
          public function sayHello() {
            parent::sayHello();
            echo 'World!';
          }
        }
        class MyHelloWorld extends Base {
          use SayWorld;
        }
        
        $o = new MyHelloWorld();
        $o->sayHello();
        ?>
        
    • 多個 Trait 使用範例 :
      • multiTrait.php
        <?php
        trait Hello {
          public function sayHello() {
            echo 'Hello ';
          }
        }
        trait World {
          public function sayWorld() {
            echo 'World';
          }
        }
        class MyHelloWorld {
          use Hello, World;
          public function sayExclamationMark() {
            echo '!';
          }
        }
        $o = new MyHelloWorld();
        $o->sayHello();
        $o->sayWorld();
        $o->sayExclamationMark();
        ?>
        
      • integrateTrait.php
        <?php
        trait Hello {
          public function sayHello() {
            echo 'Hello ';
          }
        }
        trait World {
          public function sayWorld() {
            echo 'World';
          }
        }
        trait HelloWorld{
          use Hello, World;
        }
        class MyWorld{
          use HelloWorld;
        }
        $world = new MyWorld();
        echo $world->sayHello() . " " . $world->sayWorld(); //Hello World
        ?>
        
    • 優先序問題
      • Trait 內可以使用 overwrite 功能來覆蓋父類別有的功能!
      • 優先序的範例 : orderTrait.php
        <?php
        trait Hello{
          function sayHello() {
            return "Hello";
          }
          function sayWorld() {
            return "Trait World";
          }
          function sayHelloWorld() {
            echo $this->sayHello() . " " . $this->sayWorld();
          }
          function sayBaseWorld() {
            echo $this->sayHello() . " " . parent::sayWorld();
          }
        }
        
        class Base{
          function sayWorld(){
            return "Base World";
          }
        }
        class HelloWorld extends Base{
          use Hello;
          function sayWorld() {
            return "World";
          }
        }
        $h =  new HelloWorld();
        $h->sayHelloWorld(); // Hello World
        ?>
        
    • Trait 的衝突與別名 : 使用 insteadof 與 as
      • 利用 insteadof 來解決不同 Trait 但相同方法名稱的問題
      • 例 : 有一衝突的範例 confuse.php
        <?php
        trait Game{
          function play() {
            echo "Playing a game";
          }
        }
        trait Music{
          function play() {
            echo "Playing music";
          }
        }
        
        class Player{
          use Game, Music;
        }
        $player = new Player();
        $player->play();
        ?>
        
        PS: 以上範例有兩個 Trait ,有相同的方法名稱 play()!在使用當下,就會發生衝突!
      • 修改後的 confuse.php 如下:
        <?php
        trait Game{
          function play() {
            echo "Playing a game";
          }
        }
        trait Music{
          function play() {
            echo "Playing music";
          }
        }
        
        class Player{
          use Game, Music{
            //將 Game 的 play 別名成 gamePlay
            Game::play as gamePlay;
            //使用 Music 的 play 功能,取消 Game 的 play 功能!
            Music::play insteadof Game;
          }
        }
        $player = new Player();
        $player->play();
        $player->gamePlay();
        ?>
        
  2. Trait 其它功能
    • 利用 Trait 獨特的使用功能,可以取得 private 權限的類別屬性值
      • 例 : getPritrait.php
        <?php
        trait Message {
          function alert() {
            echo $this->message;
          }
        }
        class Messenger {
          use Message;
          private $message = "This is a message";
        }
        
        $messenger = new Messenger;
        $messenger->alert(); //This is a message
        ?>
        
    • 利用 Trait 內可抽象化方法,強迫使用該 Trait 的類別,實作該抽象方法!
      • 例 : abtractTrait.php
        <?php
        trait Message {
          private $message;
              
          function alert() {
            $this->define();
            echo $this->message;
          }
          abstract function define();
        }
        
        class Messenger {
          use Message;
          function define() {
            $this->message = "Custom Message";
          }
        }
        
        $messenger = new Messenger;
        $messenger->alert(); //Custom Message
        ?>
        
    • Trait 的 use 與類別導入的 use 是不同的功能
      • Trait 的 use : 置放於 class 內部!
      • 類別導入的 use : 置放於 class 外部!

本章練習:
  • 修改你的 Human 類別,讓它可以使用 Bird 類別中的 fly 方法!

PHP 的命名空間

設定目標:
  • 了解 PHP 如何定義命名空間,改善自動載入的缺點!

命名空間概念與實作
  1. 命名空間(Namespace)
    • PSR 規範 : PHP-FIG 提出的規範,目的是讓 PHP 開發者在撰寫時有一個建議規範可遵循,使得開發者間可進行有效溝通與開發!
    • PSR-4 規範了一套 namespace 統一作法,包含了原有的 PSR-0 所規範的 autoload 作法!
    • 利用Composer 來進行 autoload 可提昇編輯效率!
    • PHP 檔案內的關鍵字 :
      • namespace : 定義類別的完整類別名稱
      • use : 導入需要使用的類別名稱
    • PSR-4 正確的命名空間,其完整的類別名稱語法如下 :
      \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
      
      • 完整的類別名稱(fully qualified class name)必須有最高層級(top-level)的命名空間(namespace),通常稱這個命名空間為「供應商命名空間(vendor namespace)」。
      • 完整的類別名稱可以有一個或多個子命名空間。
      • 一個完整的類別名稱必須以類別名稱結束。
      • 在完整的類別名稱中,底線沒有其他意義。
      • 完整的類別名稱可以由英文字母大小寫組合而成。
      • 所有的類別名稱必須是有區分大小寫的。
    • 重點 :
      • 命名空間 + 類別名稱 = 路徑 + 檔名.php
      • 命名空間、類別,都需要開頭大寫
      • 底線不要拿來當作分類,例如 : Like_Book.php、Like_Movie.php,應該改成路徑 Like/Book.php、Like/Movie.php
  2. 實作範例:
    • 安裝 Composer 至專案目錄內!(Windows 使用者可以參考這一篇)
      # yum install wget
      # cd /usr/share/nginx/html
      # wget https://getcomposer.org/installer -O composer-installer.php
      # php composer-installer.php --filename=composer --install-dir=/usr/local/bin
      # composer --version
      
    • 建立測試用目錄 :
      +Hello
      ++public
      ++-index.php
      ++src
      +++Cars
      +++-Car.php
      ++vendor (該目錄由 composer 自建,一開始不用手動建立)
      +++composer
      ++-autoload.php
      +-composer.json
      
    • 編寫 composer.json
      {
        "autoload": {
          "psr-4": {
            "Cars\\": "src/Cars"
          }
        }
      }
      
    • 初次建立名稱空間
      # composer dump-autoload
      
    • 開始建立 PHP 類別程式
      • 建立 Cars/Car.php
        <?php
        namespace Cars;
        
        class Car{
        
          protected $name;
        
          public function setName($name){
            $this->name = $name;
            return "completed...";
          }
        
          public function getName(){
            return $this->name;
          }
        }
        ?>
        
      • 建立 public/index.php
        <?php
        require_once '../vendor/autoload.php';
        
        use \Cars\Car;
        $mycar = new Car();
        $mycar->setName("Ford...");
        echo $mycar->getName();
        ?>
        
      • 使用瀏覽器 http://你的IP/Hello/public/index.php
    • 增加新的類別 : Customers
      • 在 src 目錄下建立新的目錄 Customers
        # mkdir /usr/share/nginx/html/Hello/src/Customers
        
      • 修改 composer.json
        • 加入 Customers 路徑的對應
          {
            "autoload": {
              "psr-4": {
                "Cars\\": "src/Cars",
                "Customers\\": "src/Customers"
              }
            }
          }
          
        • 再執行一次 composer
          # composer dump-autoload
          
        • 開始新增新的類別 Customer
          • 在 src/Customers 目錄下,新增 Customer.php
            <?php
            namespace Customers;
            
            class Customer{
              protected $cname;
              public function setName($cname){
                $this->cname = $cname;
                return "completed...";
              }
              
              public function getName(){
                return $this->cname;
              }
            }
            ?>
            
          • 修改 index.php 檔案內容
            <?php
            require_once '../vendor/autoload.php';
                
            use Cars\Car;
            use Customers\Customer;
                    
            $mycar = new Car();
            $mycar->setName("Ford...");
            echo "My Car: ".$mycar->getName();
            echo "
            "; $myprofile = new Customer(); $myprofile->setName("Peter"); echo "My Name: ".$myprofile->getName(); ?>
          • 在 Customers 下增加子目錄 Block
            # cd /usr/share/nginx/html/Hello/src
            # mkdir Customers/Block
            
          • 在 Block 目錄下,增加一個 Blocklist.php
            <?php
            namespace Customers\Block;
            
            use Customers\Customer;
            
            class Blocklist extends Customer {
            
              protected $state;
                    
              public function setState($state){
                $this->state = $state;
                return "Complete...";
              }
                    
              public function getState(){
                return $this->state;
              }
            }
            ?>
            
          • 修改 index.php 檔案內容
            <?php
            require_once '../vendor/autoload.php';
                
            use Cars\Car;
            use Customers\Customer;
            use Customers\Block\Blocklist;        
                    
            $mycar = new Car();
            $mycar->setName("Ford...");
            echo "My Car: ".$mycar->getName();
            echo "
            "; $myprofile = new Customer(); $myprofile->setName("Peter"); echo "My Name: ".$myprofile->getName(); echo "
            "; $mystate = new Blocklist(); $mystate->setState("Forzien..."); echo $mystate->getState(); ?>
          • 使用瀏覽器 http://你的IP/Hello/public/index.php

本章練習:
  • 修改你的 dog 、cat 以及 human 的所有類別,讓他們有自己所屬目錄,並且可以自動導入到執行程式中!

2021年3月13日 星期六

PHP 的自動載入功能

設定目標:
  • 了解 PHP 如何自動載入需要的模組程式

模組自動載入
  1. PHP 原有的模組載入方式
    • include : 載入其他的 php 程式檔!當執行錯誤時,不會停止程式運作!
    • include_once : 相同的檔案,只會載入一次!
    • require : 載入其他的 php 程式檔!當執行錯誤時,會停止程式運作!
    • reuqire_once : 相同的檔案,只會載入一次!
  2. 缺點 : 若需要載入大量檔案程式,程式碼將會十分難看與難以除錯與管理!
  3. PHP 自動導入模組方式
    • 當須要用到該使用的物件時,才去真正的引入該類別
    • __autoload 用法 :
      • 例 : 有一個目錄 Classes ,裡面有個 Member.php 的檔案,Classes 目錄外面有兩個檔案 autoload.php 以及 index.php
        +Classes
        +--Member.php
        -autoload.php
        -index.php
        
      • Member.php 檔案內容:
        <?php
        //這是 Classes/Member.php
        class Member{
          public function getMemberList(){
            echo "print member list...
        "; } } ?>
      • autoload.php 檔案內容:
        <?php
        function __autoload($className){
          $filename = __DIR__ . "/classes/" . $className . ".php";
          if (is_readable($filename)){
            require $filename;
          }
        }
        ?>
        
      • index.php 檔案內容:
        <?php
        //這是 index.php
        include_once __DIR__ . "/autoload.php";
        
        $member = new Member();
        $member->getMemberList();
        ?>
        ?>
        
      • 缺點 : __autoload() 不能重覆的被定義!
  4. 使用 SPL(Standard PHP Library)
    • spl_autoload:
      • 預設實作 __autoload() magic function
      • 當 spl_autoload_register() 沒有定義或是沒有帶任何參數的時候,預設會採用 __autoload() 這個 function
    • spl_autoload_register
      • 能夠註冊自行定義的 autoload function
      • 當 spl_autoload_register() 有註冊之後,__autoload() 將會失效,必需自己手動將 __autoload() 註冊,才能使用。
    • 例 : 在原來的範例目錄內,增加 first 以及 second 這兩個目錄以及 First.php 與 Second.php 兩個檔案!另外再新增兩個 firstAutoload.php 以及 secondAutoload.php 檔案!
      +Classes
      +--Member.php
      +first
      +--First.php
      +second
      +--Second.php
      -firstAutoload.php
      -secondAutoload.php
      -autoload.php
      -index.php
      
    • First.php 檔案內容:
      <?php
      //這是 first/First.php
      class First{
        public function doSomething(){
          echo "I am first class...
      "; } } ?>
    •     
    • Second.php 檔案內容:
      <?php
      //這是 second/Second.php
      class Second{
        public function doSomething(){
          echo "I am second class...
      "; } } ?>
    •     
    • firstAutoload.php 檔案內容:
      <?php
      //這是 firstAutoload.php
      function firstAutoload($className){
        $filename = __DIR__ . "/first/" . $className . ".php";
        if (is_readable($filename)){
          require $filename;
        }
      }
      //向 spl_autoload 註冊這個方法的名稱
      spl_autoload_register('firstAutoload');
      ?>
      
    •     
    • secondAutoload.php 檔案內容:
      <?php
      //這是 secondAutoload.php
      function secondAutoload($className){
        $filename = __DIR__ . "/second/" . $className . ".php";
        if (is_readable($filename)){
          require $filename;
        }
      }
      //向 spl_autoload 註冊這個方法的名稱
      spl_autoload_register('secondAutoload');
      ?>
      
    • 修改 index.php 檔案內容:
      <?php
      //修改後的 index.php
      include_once __DIR__ . "/firstAutoload.php";
      include_once __DIR__ . "/secondAutoload.php";
      
      $first = new First();
      $first->doSomething();
      
      $second = new Second();
      $second->doSomething();
      ?>
      
    • 缺點 : 每新增一個目錄,就需要寫一個 autoload 檔案!不好管理!
    • 改進方式 : 寫一個 allAutoload.php,再使用 array、foreach 導入!
      <?php
      //這是 allAutoload.php
      function allAutoload($className){
      $folders = array(__DIR__ . "/first/",
                       __DIR__ ."/second/",
                       );
      
      foreach ($folders as $folder){
          $fileName = $folder . $className . ".php";
          if (is_readable($fileName)){
             require $fileName;
          }
        }
      }
      
      //註冊
      spl_autoload_register('allAutoload');
      ?>
      
    • 再次修改 index.php 檔案內容:
      <?php
      //又修改了 index.php
      include_once __DIR__ . "/allAutoload.php";
      $first = new First();
      $first->doSomething();
      
      $second = new Second();
      $second->doSomething();
      ?>
      
    • 缺點 : 每次新增一個 class 目錄,就要異動一次 autoload 檔案!

本章練習:
  • 修改你的 dog 、cat 以及 human 的所有類別,讓他們可以自動導入到執程式中!

PHP 多型方法與多載功能

設定目標:
  • 了解 PHP 如何使用多型方法
  • 了解 PHP 如何使用多載功能

多型概念與使用方法
  1. 多型(Polymorphism)
    • 使用概念與方法:
      • 有繼承的關係才能使用多型
      • 利用有相同父類別的關係,進行不同子類別的方法實作,產生不同的結果!
    • 例:demo5.php
      <?php
      abstract class Animal {
        public function sleep(){
            echo '睡';
        }
      }
      class Dog extends Animal {
        public function move(){
            echo '跑';
        }
      }
      class Bird extends Animal{
        public function move()
        {
            echo '飛';
        }
      }
      class Action{
        public function actionMove(Animal $obj)
        {
            $obj->move();
        }
      }
      
      $dog = new Dog();
      $bird = new Bird();
      $action = new Action();
      $action->actionMove($dog);
      $action->actionMove($bird);
      ?>
      
多載功能的應用
  1. 多載(overloading)
    • PHP 無法像其他物件導向程式語言,可以利用相同名稱,不同參數屬性值來實作多載功能!
    • PHP 利用自定義的 Magic methods 來實作多載功能!
    • 屬性多載的 magic function :
      • __set(): 若有屬性名稱是設定未定義或無法讀取的,就「設定」對應的屬性值!
      • __get(): 若有屬性名稱是設定未定義或無法讀取的,就「取得」對應的屬性值!
      • __isset(): 查詢某個屬性是否有被定義!
      • __unset(): 解除某個屬性定義值!
      • 範例 : Person.php
        <?php
          class Person {
              private $sex;
              public function __set($name, $value){
                
                //限制不可動態產生屬性
                if (isset($this->$name)) {
                    return $this->$name = $value;
                } else {
                    return null;
                }
              }
              // 取得屬性名稱的值
              public function __get($name){
                return $name;
              }
              // 判斷是否有該屬性參數   
              public function __isset($name){
                return $name;
              }
              // 取消該屬性
              public function __unset($name){
                return $name;
              }
            }
            
            $person = new Person();
            //Person 類別沒有 name 這個屬性名稱
            //PHP_EOL 空隔或是換行
            $person->name = 'PHP';
            echo $person->name.PHP_EOL;
            // sex 這個屬性是無法取得的
            echo $person->sex.PHP_EOL;
            echo isset($person->address);
            unset($person->name);
        ?>
        
    • 方法多載的 magic functions :
      • __call() : 當呼叫一個未定義的物件方法時,會呼叫本法函數!
      • __callStatic() : 當呼叫一個未定義的靜態物件的方法時,會呼叫本法函數!
      • 例 : Shape.php
        <?php
        class Shape {
          const PI = 3.142 ;
          // name 是方法名稱,arg 則是陣列名稱
          function __call($name,$arg){
            if($name == 'area')
              switch(count($arg)){
                case 0 : return 0 ;
                //self 指物件自己
                case 1 : return self::PI * $arg[0] ;
                case 2 : return $arg[0] * $arg[1];
              }
          }
          function __callStatic($name,$arg){
            return array(3,5);
          }
        }
        $circle = new Shape();
        echo $circle->area(3);
        $rect = new Shape();
        echo $rect->area(8,6);
        echo Sharp::hello()[1];
        ?>
        

本章練習:
  • 寫個利用衣服的類別,讓你的 dog 、cat 以及 human 穿上適合的衣服!
  • 寫個檢查有沒有穿衣服的方法,讓 dog 、cat 不用穿衣服,以及 human 穿上泳衣!

PHP 靜態屬性與匿名類別

設定目標:
  • 了解 PHP 靜態屬性的用法
  • 了解 PHP 匿名類別概念與應用方法

靜態屬性概念與使用方法
  1. 靜態屬性(static)
    • 作用:
      • 用於不會改變的類別屬性與方法
      • 不需要實例化產生物件,直接呼叫類別即可使用
    • 例:MathRate.php (計算複利用的方法)
      <?php
      class MathRate{
        public static function ComplexRate($principal,$yearRate,$period,$years){
           $result = 0;
           $result =  $principal * pow((1 + ((float)$yearRate/$period)),($period*$years));
           return $result;
        } 
      }
      ?>
      
    • 利用一個 demo4.php 來實現上述程式:
      <?php
        include "MathRate.php";
        echo MathRate::ComplexRate(1000,0.18,12,3);
      ?>
      
匿名類別觀念與應用
  1. 匿名類別(Anonymous class)
    • 作用
      • 有些類別用完即丟,沒有需要一直存在,即可使用匿名類別,減輕程式的複雜程度!
    • 範例 : Application.php
      <?php
      interface Logger {
        public function log(string $msg);
      }
      class Application {
        private $logger;
        public function getLogger(): Logger {
          return $this->logger;
        }
        public function setLogger(Logger $logger) {
          $this->logger = $logger;
        }
      }
      $app = new Application;
      // 使用 new class 建立匿名類別
      $app->setLogger(new class implements Logger {
        public function log(string $msg) {
          print($msg);
        }
      });
      
      $app->getLogger()->log("這是一個匿名類別的例子");
      ?>
      

本章練習:
  • 寫個疫苗的匿名類別,讓你的 dog 以及 cat 接種疫苗!
  • 寫個計算寵物一年花費的費用計算靜態程式,算一下你的寵物一年的花費!

PHP 介面與抽象類別的應用

設定目標:
  • 了解介面與抽象類別的概念
  • 實作介面與抽象類別的方法

介面概念與使用方法
  1. 介面(interface)
    • 作用:
      • 定義相同的功能名稱,但可以由執行的類別,各自實作功能!
      • 有實作介面的類別,一定要實作內容!
      • 介面可以繼承其他的介面!
      • 類別可以同時執行多個介面!
    • 例:Bark.php (吠叫...)
      <?php
        interface Bark{
          public function bark();
        }
      ?>
      
    • 例:Swim.php (游泳...)
      <?php
        interface Swim{
          public function swim();
        }
      ?>
      
    • 例:Human.php (建一個人類的類別...)
      <?php
        include "Bark.php";
        include "Swim.php";
        class Human implements Bark, Swim{
          public function bark(){
            echo "人類叫聲...是在叫什麼啦!!";
          }
          public function swim(){
            echo "人類在游泳...不是在洗澡嗎?";
          }
        }
      ?>
      
    • 利用一個 demo3.php 來實現上述幾個程式:
      <?php
        include "Human.php";
        $man = new Human();
        echo $man->bark();
        echo $man->swim();
      ?>
      
抽象類別觀念與應用
  1. 抽象類別 (Abstract)
    • 作用
      • 父類別在使用介面之後,必須要實作該介面功能內容!
      • 子類別在繼承父類別之後,如想要改變介面功能內容,必須使用覆寫的方式!
      • 父類別若不想實作介面方法,子類別又需要定義介面功能,可以將父類別抽象化,即可不用實作介面方法!
      • 子類別繼承抽象父類別之後,必須要實作父類別的介面方法!
    • 範例 : 修改 dog.php
      <?php
      include "Bark.php";
      abstract class dog implements Bark {
         // 設定狗的屬性
         public $name;
         public $color;
         public $style;
         
         //設定建構子
         public function __construct($name,$color,$style){
           $this->name = $name;
           $this->color = $color;
           $this->style = $style;
         }
      
         public function dogRun(){
           echo "狗狗跑步中...";
         }
         // 修改狗叫的功能
         public function Bark(){
           //這裡保持空白
         }
      
         public function __destruct(){
           echo "狗狗回家了...";
         }
      }
      ?>
      
    • 範例 : 修改 Poodle.php
      <?php
      include "dog.php";
      
      class Poodle extends dog{
        protected $size;
      
        public function __construct($name,$color,$style,$size){
          parent::__construct($name,$color,$style);
          $this->size = $size;
        }
        // 實作父類別的狗叫 function
        public function Bark(){
          echo "狗叫...但小聲....";
          //呼叫父類別的 dogBark()
        }
      }
      ?>
      
    • 利用 demo2.php 來使用上述程式:
      <?php
        include "Poodle.php";
      
        $mydog = new Poodle("Windy","白色","貴賓狗",30);
        //修改此行
        echo $mydog->Bark();
      ?>
      

本章練習:
  • 修改 dog.php 檔案,使用 Bark.php 介面程式
  • 修改 cat.php 檔案,將 cat 類別抽象化,並且使用 Bark.php 介面程式

2021年3月12日 星期五

PHP 物件封裝與繼承方法

設定目標:
  • 了解物件導向封裝與繼承的概念
  • 了解 PHP 使用封裝與繼承的方法

物件封裝概念與方法
  1. 封裝 (Encapsulation)的目的 :
    • 用於限制物件資源的使用
    • 存取權限分類:
      • public : 可以在任何地方存取該物件資源!若沒指定,PHP 會指定其為預設值!
      • protected : 可以在自身類別和子類別中存取!
      • private : 只能在自身類別中存取!
    • 例:MyDog.php
      <?php
        class MyDog {
          // 定義 dog 的種類「屬性」,並設定「公開」權限
          public $raise = "柴犬";
          // 定義 dog 的年紀「屬性」,並設定「保護」權限
          protected $age = 5;
          // 定義 dog 的名字「屬性」,並設定「私人」權限
          private $name = "Peter";
          
          // 定義取得 dog 屬性值取得的「方法」, 並設定「公開」權限
          public function getPara(){
            echo "MyDog->raise : ".$this->raise."<br />";
            echo "MyDog->age : ".$this->age."<br />";
            echo "MyDog->name : ".$this->name."<br />";
          }
         } 
          // 產生實際物件
          $mydog = new MyDog();
          // 利用 getPara() 方法,取出實際物件的屬性值
          $mydog->getPara();
          // 直接使用物件,取出實際物件的屬性值,並且與 getPara() 方法對照
          echo "mydog->raise : ".$mydog->raise."<br />";
          echo "mydog->age : ".$mydog->age."<br />";
          echo "mydog->name : ".$mydog->name."<br />";
      ?>
      
  2. 建構子(constructor)與解建構子(destructor)
    • 建構子 : 用於建立物件時,一併設定好物件相關屬性與設定!
    • 解建構子 : 用於消除物件時,一併解除物件相關屬性與設定!通常放於類別最後面,程式會自動執行,不需要特別呼叫!
    • 例 : 修改先前的 dog.php 程式
      <?php
      class dog {
         // 設定狗的屬性
         public $name;
         public $color;
         public $style;
         
         //設定建構子
         public function __construct($name,$color,$style){
           $this->name = $name;
           $this->color = $color;
           $this->style = $style;
         }
      
         public function dogRun(){
           echo "狗狗跑步中...";
         }
      
         public function dogBark(){
           echo "狗叫...";
         }
      
         public function __destruct(){
           echo "狗狗回家了...";
         }
      }
      ?>
      
    • 利用 demo.php 來使用上述 dog.php 程式:
      <?php
          include "dog.php";
          $myDog = new dog("來福","白色","台狗土狗");
          $myDog->dogRun();
      ?>
      
物件繼承觀念與應用
  1. 繼承(extends)
    • 作用
      • 避免寫出重複的程式碼!
      • 依據需求,重複利用相同程式碼,做出功能不同的程式!
      • 子類別繼承父類別的屬性與方法,免去定義相同功能!
      • 必要時,子類別除了可以定義自己的屬性與方法,也可改寫父類別的屬性與方法!
      • 語法格式 :
        class 類別名稱 {
        class 子類別名稱 extends 父類別名稱 {
          可執行的程式;
        }
        
      • 範例 : 牧羊犬是狗的一個子類別 Shepherd.php
        <?php
          // 引入 dog 類別
          include "dog.php";
          // 定義牧羊犬 Shepherd 是 狗 dog 的子類別
          class Shepherd extends dog{
             // 定義子類別需要的屬性
             protected $age;
        
             public function __construct($name,$color,$style,$age){
               // 繼承父類別的屬性
               parent::__construct($name,$color,$style);
               $this->name = $name;
               $this->color = $color;
               $this->style = $style;
               $this->age = $age;
              }
             // 定義子類別的方法 
             public function doWork(){
               echo "趕羊..."."
        "; } // 覆寫(override)解構子 public function __destruct(){ echo "趕羊到家了"; } } ?>
      • 利用 demo1.php 來使用上述 Shepherd.php 程式:
        <?php
          include  "Shepherd.php";
          $mydog = new Shepherd("peter","棕色","牧羊犬",10);
          echo $mydog->name."
        "; echo $mydog->color."
        "; echo $mydog->style."
        "; echo $mydog->doWork()."
        "; //子類別未改寫父類別的方法 echo $mydog->dogRun()."
        "; ?>
  2. 覆寫(override)
    • 作用  
      • 子類別需要改寫父類別中,相同的方法名稱時!
      • 覆寫後,仍可以呼叫父類別中相同的方法!
    • 範例 : Poodle.php
      <?php
      include "dog.php";
      
      class Poodle extends dog{
        protected $size;
      
        public function __construct($name,$color,$style,$size){
          parent::__construct($name,$color,$style);
          $this->size = $size;
        }
        // 覆寫狗叫的 function
        public function dogBark(){
          echo "狗叫...但小聲....";
          //呼叫父類別的 dogBark()
          parent::dogBark();
        }
      }
      ?>
      
    • 利用 demo2.php 來使用上述 Poodle.php 程式:
      <?php
        include "Poodle.php";
      
        $mydog = new Poodle("Windy","白色","貴賓狗",30);
        echo $mydog->dogBark();
      ?>
      

本章練習:
  • 寫兩支程式褲子與上衣,表述其繼承衣服的類別,並計算分別購買10件的費用!

PHP 類別宣告與物件使用方式

設定目標:
  • 了解基本物件導向觀念與應用
  • 了解 PHP 類別與物件的使用方式

基本物件導向觀念
  1. 物件導向的目的 :
    • 增加程式的重複利用性
    • 減少重複撰寫程式
    • 增加程式可擴充及延展性
    • 增加開發程式的靈活性
基本物件導向觀念
  1. 類別與物件 (Class &  Object)
    • 類別 : 定義物件的內容!其包含類別的函數與變數!
      • 函數 : 類別的方法
      • 變數 : 類別的屬性
      • 語法格式 :
        class 類別名稱 {
          // 設定變數
          public 變數名稱;
          .....
          // 設定函數
          public function 函數名稱(參數1,參數2,....){
            // 可以執行程式的區塊
          }
        }
        
      • 範例 : dog.php
        <?php
          class dog {
            // 定義 dog 的年紀「屬性」
            public $age;
            // 定義取得 dog 年紀屬性值的「方法」
            public function getAge(){
              return $this->age;
            }
          }
        ?>
        
      • 「->」: 代表呼叫物件的屬性或方法名稱
      • this : 表示「這個物件」自己
    • 物件 : 實際使用的程式碼,由類別實例化而來
      • 語法格式 :
        變數名稱 = new 類別名稱;
        
      • 範例 : demo.php
        <?php
            include "dog.php";
            $mydog = new dog();
            $mydog->age = 10;
            echo "我的狗年紀 : ".$mydog->getAge();
        ?>
        

本章練習:
  • 寫一支有關於衣服的類別,並計算購買10件衣服的費用!

PHP 函數基本應用

設定目標:
  • 了解 PHP 函數宣告與使用方式

PHP 函數宣告與呼叫方式
  1. 函數的宣告
    • 函數的作用:將功能相同的程式碼提出,以減少撰寫相同功能的程式碼
    • 使用方式:
      // 有數值需要傳遞時,需要設定參數
      // 若無傳遞數值的必要時,可不用設定參數
      function 函數名稱 (參數1,參數2,.....){
          需要執行的程式;
      
          //無需將執行結果傳出時,可以不用寫回傳值
          return 回傳值;
      }
      
    • 範例 : ex5_1.php
      <?php
        // 顯示名字
        function name(){
            echo "Peter";
        }
      
        // 計算成績等級
        function score($i) {
            $j = "F";
            $level = intval($i / 10);
            switch ($level){
                case 10:
                case 9:
                  $j = "A";
                  break;
                case 8:
                  $j = "B";
                  break;
                case 7:
                  $j = "C";
                  break;
                case 6:
                  $j = "D";
                  break;
                default:
                  $j = "E";
            }
            return $j;
        }
      
        echo name();
        $backscore = score(85);
        echo " 成績等級:$backscore";
      ?>
      
  2. 可變長度引數的使用
    • 若傳遞進入函數的參數個數不確定,可以使用可變長度引數的參數設定
    • 語法格式 :
      //重點在於那個「...」
      function 函數名稱 (...$參數名稱){
          需要執行的程式碼;
          return 回傳值;
      }
      
    • 範例 : ex5_2.php
      <?php
          function sum(...$numbers){
              $total = 0;
              foreach ($numbers as $i){
                  $total += $i;
              }
              return $total;
          }
      
          echo "總共是:".sum(1,3,5,7,9);
      ?>
      
  3. 遞迴函數
    • 基本精神 : 函數自己呼叫自己!
    • 範例 : ex5_3.php
      <?php
        function table99($i=2,$j=1){
          if ($j > 9){
            $i++;
            $j = 1;
            echo "
      "; } if ( $i <= 9 ){ printf("%d*%d=%d \t",$i,$j,($i*$j)); $j++; table99($i,$j); } } echo table99(); ?>
  4. 參數與回傳值宣告
    • PHP 7 之後,函數的參數與回傳值,可宣告資料型態
    • 範例 : ex5_4.php
      <?php
        function add(int $i,int $j):int{
          return ($i+$j);
        }
        echo add(3,5);
      ?>
      

本章練習:
  • 寫一支費式數列程式,計算前10個費式數列數值!

PHP 迴圈語法的運用

設定目標:
  • 了解 PHP 迴圈結構與使用方式

PHP 迴圈結構基本用法
  1. for 迴圈 :
    • 用於可數的重複工作
    • 語法格式 :
      for (起始值;條件式;步進值){
          需要重複做的事;
        }
      
    • 範例 : ex4_6.php
      <?php
        // 從 1 加到 50 的整數和
        // 以下方式只是為了說明 for 迴圈的使用方式,不是好的程式碼寫法!!
        $sum = 0;
        for ($i = 1; $i <= 50; i++){
            $sum += $i;
        }  
        echo "總合是: $sum";
      ?>
      
  2. while 迴圈 :
    • 用於有條件限制的重複工作
    • 先判斷條件,成立後再執行工作!
    • 語法格式 :
      while ( 條件式 ){
          需要重複做的事;
        }
      
    • 範例 : ex4_7.php
      <?php
        $sum = 0;
        while ( $i <= 50 ){
          $sum += $i;
          $i++;
        }
      ?>
      
  3. do … while 迴圈 :
    • 用於有條件限制的重複工作
    • 先工作,再進條件判斷,決定需不需要繼續執行!
    • 語法格式 :
      do {
          需要重複做的事;
        } while (條件式);
      
    • 範例 : ex4_8.php
      <?php
        $sum = 0;
        $i = 1;
        do {
          $sum += $i;
          $i++;
        } while ($i <= 50);
      ?>
      
  4. 無窮迴圈 :
    • 永不停止的重複執行
    • 建議放入一個可中斷程式的判斷程式
    • 語法格式 :
      for (;;){ }
        while(true){ }
        do { } while (true);
      
    • 範例 : ex4_9.php
      <?php
      $sum = 0;
        $i = 0;
        while (true){
          $i++;
          $sum += $i;
          if ( $sum >= 100) break;
        }
        echo "\$sum : $sum";
      ?>
      
  5. 巢狀迴圈
    • 迴圈內有迴圈,即為巢狀迴圈!
    • 沒事請少用巢狀迴圈
    • 語法格式 :
      //以下僅表示雙層巢狀迴圈,可以再多幾層迴圈
        for(起始值;條件式;步進值){
          for(起始值;條件式;步進值){
            需要重複做的事;
          }
        }
      
        while(條件式){
          while(條件式){
            需要重複做的事;
          }
        }
      
        do {
          do {
            需要重複做的事;
          } while (條件式);
        }while (條件式);
      
    • 範例 : ex4_10.php
      <?php
      //九九乘法表
      for ($i = 2; $i < 10; $i++){
        for ($j = 1; $j < 10; $j++){
          printf("%d*%d=%d \t",$i,$j,($i * $j));
        }
        printf("\n");
      } 
      ?>
      
  6. break
    • break 用法 : 跳出迴圈、switch 時使用!
    • 語法格式 :
      break;   //跳出目前的迴圈
        break 1; //跳出目前的一層迴圈
        break 2; //跳出目前的二層迴圈
      
    • 範例 : ex4_11.php
      <?php
      while (true){
          echo "這是第一層迴圈!
      "; while (true){ echo "這是第二層迴圈!
      "; break 2; } } echo "己跳出二層迴圈!"; ?>
  7. continue
    • continue 用法 : 于迴圈中,略過這一次,執行下一次的工作!
    • 範例 : ex4_12.php
      <?php
          while($i <= 10){
            if ( $i == 5) {
              echo "略過 \$i = $i 
      "; continue; } echo $i."
      "; } ?>

本章練習:
  • 寫一支程式判斷成績等級:

PHP 控制結構的運用

設定目標:
  • 了解 PHP 控制結構與使用方式

PHP 決策控制基本用法
  1. 語法:if...else
    • 格式 :
      if (條件式){
        條件式為真時,執行本程式區塊
      } else {
        條件事為假時,執行本程式區塊
      }
      
    • 範例 : ex4_1.php
      <?php
      $i = 10;
      if ( $i > 10 ){
           echo "Hello World";
         } else {
           echo "Good Bye";
      }
      if ( $i == 10 ) echo "Too Many";
         else $i += 100;
         echo $i; 
      ?>
      
  2. 三元運算子(一) : 「 ? : 」
    • 格式 :
      (條件式) ? 條件為真執行這行 : 條件為假執行這行 ;
      
    • 範例 : ex4_2.php
      <?php
        $i = 10;
        echo ($i > 101)?"大":"小";
      ?>
      
  3. 三元運算子(二) : 「 ?? 」
    • 格式 :
      (內容值) ?? 內容值為Null時,顯示該結果 ;
      
    • 範例 : ex4_3.php
      <?php
        $input = isset($value)? $value : "空的";
        echo $input."\n";
        $input = $value ?? "空的";
        echo $input;
      ?>
      
  4. 語法:if … elseif … else
    • 格式 :
      if (條件式1) {
        條件式 1 成真時,執行此程式區塊;
      } elseif (條件式2) {
        條件式 2 成真時,執行此程式區塊;
      } else {
        以上條件式均為假時,執行此程式區塊;
      }
      
    • 範例 : ex4_4.php
      <?php
      $i = 10;
      if ( $i >= 200 ){
        echo "\$i 大於 200";
      } elseif ( $i >= 100 ){
        echo "\$i 大於100,小於200";
      } else {
        echo "\$i 小於 100";
      }
      ?>
      
  5. switch 語法 : 一種判斷可得多種不同結果
    • 格式 :
      switch(條件變數或表達式){
        case "A":
          當結果為 A 時,執行本區塊程式;
          break;
        case "B":
          當結果為 B 時,執行本區塊程式;
          break;
        default:
          沒有符合的結果,執行本區程式;
      }
      
    • 範例 : ex4_5.php
      <?php
        $fruit = "Apple";
        switch($fruit){
          case "apple":
            echo "這是 apple";
            break;
          case "banana":
            echo "這是 banana";
            break;
          default:
            echo "打錯字了嗎";
        }
      ?>
      

本章練習:
  • 寫一支程式判斷成績等級:

2021年3月11日 星期四

PHP 陣列基本應用

設定目標:
  • 了解 PHP 陣列與基本用法

PHP 陣列與基本用法
  1. 宣告方式
    • 格式 :
      • 一維 : $變數名稱[“key” or index]=value;
      • 二維 : $變數名稱[“key” or index][“key” or index]=value;
        • 可以視為多個一維陣列組合起來!
      • 多維 : []一直追加即可!
    • 例 : ex3_11.php
      <?php  //一維陣列
      $eggbox["土雞"]=30;
      $eggbox[1]=100;
      $eggbox[]=20;
      $eggbox["duck"]=50;
      $drinkbox=("啤酒"=>70,"cola"=>30);
      $foodbox=["飯團"=>50];
      echo $eggbox;
      echo $foodbox;
      echo $drinkbox;

      //二維陣列
      $lunch[0]["素食"]=100;
      $lunch[0]["葷食"]=150;
      $lunch["麵類"]["拉麵"]=200;
      $lunch["飯類"]["雞肉飯"]="今天不賣";
      $lunch[1]=array("廣東粥"=>80,"炸雞排"=>70);
      echo $lunch; ?>
  2. 新增資料方式
    • 直接新增方式!
    • 使用 array_push() 函數
    • 例 : ex3_12.php
      <?php
      $fruits = array("Apple","Pineapple");
      print_r($fruits);
      $fruits[] = "Banana";
      print_r($fruits);
      array_push($fruits,"Starfruit");
      print_r($fruits); ?>
  3. 刪除資料方式
    • 重新寫入陣列!
    • 使用 array_pop() 函數
    • 例 : ex3_12.php
      <?php
      $fruits = array("Apple","Pineapple","Banana","Starfruit");
      print_r($fruits);
      $fruits = array("Apple","Pineapple","Starfruit");
      print_r($fruits);
      array_pop($fruits);
      print_r($fruits); ?>

PHP 常見運算子

設定目標:
  • 了解 PHP 運算子種類與用法

PHP 運算子種類與用法
  1. 運算式與運算子
    • 例 : $a = $b + $c
      • 運算元 : $a $b $c
      • 運算子 : +
  2. 運算子的優先順序
    1. 物件建立 : 複製(clone)、新增(new)
    2. 陣列 : []
    3. 轉型與遞增、遞減 : ++、--、intval()!例:
      • ++$a : 先加再回傳
      • $a++ : 先回傳再加
    4. 邏輯運算子 : (非)「 !」
    5. 算術運算子 : 「 * 」、「 / 」、「 % 」(取餘數)
    6. 算術運算子 : 「+」、「-」、「.」(字串運算子)
    7. 比較運算子 : 「>」、「<」、「>=」、「<=」、「==」、「!=」、「===」(型態也要相同)
    8. 邏輯運算子 : (且)「&&」、(或)「||」
    9. 條件運算子 : 「?:」(三元運算子)
    10. 指定運算子 : 「=」、「+=」、「-=」、「*=」、「/=」、「%=」、「.=」
      • 例 : $a += $b --> $a = $a + $b
      • 例 : $a = 10
    11. 邏輯運算子 : 「and」、「or」、「xor」
      • 回傳值通常是 true 或 false !!
    12. 例 : ex3_9.php
      <?php
        $a = 10;
      $b = 20;
      echo '$a = 10'."\n";
      echo '$b = 20'."\n";
      echo '$a + $b = '.($a + $b)."\n";
      echo '$a - $b = '.($a - $b)."\n";
      echo '$a * $b = '.($a * $b)."\n";
      echo '$a / $b = '.($a / $b)."\n";
      echo '$a++ = '.($a++)."\n";
      echo '$a = '.($a)."\n";
      echo '++$a = '.(++$a)."\n";
      echo '$a = '.($a)."\n";
      echo '$b % $a = '.($b%$a)."\n";
      echo '$a > $b '.($a > $b ? 'true' : 'false')."\n";
      echo '$a += 1 ==> '.($a += 1)."\n";
      echo '$a = '.($a)."\n";
      echo '$a *= $b ==> '.($a *= $b)."\n";
      echo '$a = '.($a)."\n";
      echo '$a and $b ==> '.($a and $b)."\n";
      echo '$a or $b ==> '.($a or $b)."\n"; ?>
  3. 太空船運算子
    • 例 : ex3_10.php
      <?php
         echo 1<=>1;
      echo 1<=>2;
      echo 2<=>1; ?>

PHP 的基本資料型態

設定目標:
  • 了解 PHP 標準資料型態種類
  • 了解 PHP 資料型態轉換方式

PHP 標準資料型態
  1. 整數(Integer) : 32 bits or 64 bits
    • PHP_INT_MAX : 該平台最大整數值
    • PHP_INT_SIZE : 該平台整數位元值大小
    • 運算過程中,若超出整數型態值,則自動轉成浮點數!
  2. 浮點數(float) : 32 bits or 64 bits
    • 又稱實數(real),專用於存放有小數點的數字資料型態
    • 因為 PHP 屬弱型別資料型態,所以 float or double 都是相同資料型態!
    • e : 科學表示法,表示以10為底的指數
      • 例 : 9.773e3 = 9773
  3. 字串 : 沒有大小限制
    • 單引號 : 單引號中的變數不會轉成內容值
    • 雙引號 : 雙引號中的變數會轉成內容值
    • 跳脫字元 : 使用反斜線「 \ 」
      • \t : 相等於 [Tab] 鍵
      • \n : 換行,並移至行頭
      • \r : 換行
  4. 布林值(boolean) :
    • 表達事件的「真」或「假」!
    • 值 : true or false / True or False / TRUE or FALSE / 其它0以外的值:true or 0:false
    • 例 : ex3_4.php
      <?php
        $t = true;
      $f = false;
      echo "\$t 值 : $t 數字 : (int)$t "."<br />";
      echo "\$f 值 : $f 數字 : (int)$f "."<br />"; ?>
  5. 陣列(array) :
    • 把相同的資料型態的若干個變數集合起來,就成了陣列!
    • 陣列可以是一維、二維,甚至是多維!
    • 陣第一筆資料,由索引值為 0 開始配置!
    • 例 : ex3_5.php
      <?php
        $x[0] = "Hello";
        echo $x[0];
      ?>
      
      PS:這邊只介紹陣列資料型態,使用方式則在後來的章節才會說明!
  6. 物件(object) :
    • 利用 class 關鍵字定義一個類別(模型),再利用 new 關鍵字來建立這個類別的物作(實例)!
  7. 資源(resource) :
    • 透過專門的函數來建立和使用,負責與外部資源的聯繫!
    • 例 : XML文件、資料庫連線、讀寫外部檔案…等等!
  8. 空值(NULL) :
    • 表示沒有任何內容的變數!
    • 例 : ex3_6.php
      <?php
        $a = NULL;
        echo "\$a = $a";
      ?>
      
PHP 資料型態轉換
  1. 強制轉換
    • 轉換成整數 : (int) (integer)
    • 轉換成浮點數 : (float) (double) (real)
    • 轉換成字串 : (string)
    • 轉換成布林值 : (bool) (boolean)
    • 轉換成二進位字串 : (binary)
    • 轉換成陣列 : (array)
    • 轉換成物件 : (object)
    • 轉換成 NULL : (unset)
    • 例 : ex3_7.php
      <?php
         $pi = 3.141592;
         echo "\$pi 轉成整數 : ".(int)$pi;
         $input = "3.141592pi";
         echo "pi 轉成浮點數 : ".(float)$input;
      ?>
      
  2. 以函數轉換
    • settype(): 需要輸入兩個參數,一是變數,二是要轉換的資料型態!
      • 資料型態參數 : “integer”、“int”、“float”、“string”、“boolean”、“bool”、“array”、“object”、“null”
    • 轉換成功回傳 true,轉換失敗回傳 false !!
    • 例 : ex3_8.php
      <?php
        $pi = 3.141592;
        settype($pi, "integer");
        echo "\$pi 轉成整數: ".$pi;
        $piString = "3.141592circle";
        echo "是否有轉成功".settype($piString, "float");
        echo "\$piString 是: ".$piString;
      ?>
      
    • 其他轉換函數 :
      • intval() : 轉換成整數
      • floatval()、doubleval(): 轉換成浮點數
      • strval() : 轉換成字串
    • gettype() : 取得資料型態
    • intdiv() : 取餘數

2021年3月5日 星期五

PHP 環境安裝(二)

設定目標:
  • 在 Windows 10 上使用 VSCode 做為 PHP IDE 環境
快速操作流程:
  1. 在 PHP 官網上,下載 VS16 x64 Non Thread Safe 的 ZIP 套件
  2. 在 C 碟建立一個 php 目錄
  3. 將下載的檔案,移至 php 目錄內
  4. 按滑鼠右鍵,解壓縮全部!
  5. 解壓縮目錄到 php 目錄下即可!
  6. 設定環境變數,將 php 目錄加入 path 路徑內!開始->設定->系統->關於->進階系統設定->環境變數->系統變數->Path->編輯->新增
  7. 開啟命令提示字元,進行確認!
  8. 到 VSCode 官網上,下載 Windows 版本的安裝檔!
  9. 執行安裝工作!可一鍵到底!
  10. 安裝完後成,執行 VSCode !
  11. 使用 Extension 安裝 PHP Extension Pack 開發工具!
  12. 新增一個檔案
  13. 將檔案存成 hello.php ,並在檔案內寫入下列程式:
    <?php
         print "Hello World";
    ?>
    
  14. 開啟 VSCode Setting 功能,進行 php 環境設定:
  15. 設定 PHP 可執行檔的目錄位置!
  16. 設定檔內容如下圖所示:
  17. 關閉 VSCode ,重新開啟
  18. 開啟 Terminal 視窗,執行 php 程式!

PHP 變數的使用

設定目標:
  • 了解 PHP 變數的使用方式
  • 了解 PHP 變數命名的習慣與編排格式

PHP 變數類型與使用方式
  1. PHP 的變數
    • 定義 : 利用一個名稱,暫時記錄某些資料。
    • 命名規則 : $<變數名稱>
      • 以 $ 為開頭  
      • 變數名稱開頭字元為字母或底線,不能是數字!
      • 大小寫有別
    • 內容值的宣告:
      • ‘’ or “” : 表示內容值是文字
      • 數字不需要使用 ‘’ or “”
      • 變數若沒宣告內容值,則以預設值填入!
        • 整數、浮點數 : 0
        • 字串 : 空字串
        • 布林值 : false
        • 陣列 : 空陣列
    • 例 : ex3_1.php
      <?php
          // 變數 a 沒宣告就使用,會產生 E_NOTICE 的警告
          echo '$a: '.$a.'<br />';
          $name = 100;
          echo '$name: '.$name.'<br />';
          $name = 'David';
          echo '$name: '.$name.'<br />';
          $a = $a + 100;
          echo '$a: '.$a.'<br />';
      ?>
      
  2. 變數的存活範圍
    • 區域變數 : 變數的內容值只能在函數(function)內使用
    • 全域變數 : 變數的內容值可在整個程式內使用
    • 例 : ex3_2.php
      <?php
           $x = 1;
           function hello($x){
             $sum = $x * 2;
             echo "函數執行結束 <br />";
           }
      ?>
      <p> -------我是分隔線------</p>
      <?php
           hello($x);
           echo "x=$x<br />";
           echo "sum=$sum<br />";
      ?>
      
  3. 常數
    • 常使用,但永不改變的數值
    • 利用 define 函數定義常數名稱,方便記憶
    • 例 : ex3_3.php
      <?php
           define('PI', 3.1415926);
           echo "圓周率:".PI;
      ?>
      

2021年3月4日 星期四

PHP 程式寫作方式

設定目標:
  • 了解 PHP 程式語言寫作方式
  • 了解 PHP 程式語言寫作習慣與編排格式

PHP 程式寫作常見方式:
  1. HTML 內嵌 PHP 程式標籤 :
    <?php
    你的 php 程式碼;
    ?>
    • 範例 : hello.php
      <!doctype html>
      <html lang="en">
      <head>
      <title>Hello World</title>
      </head>
      <body>
      <?php
           print "Hello World";
      ?>
      </body>
      </html>
      
    • VSCode 使用提示:
      • 選擇 hello.php 頁籤
      • 直接輸入 html ,在輔助視窗中,選擇 html:5
      • 在<body>標籤底下輸入範例內容!
      • 將檔案存檔
  2. PHP 包含 HTML 標籤:
    • 範例1 : world.php
      <?php
        print <<<_HTML_
             <form method="post" action="$_SERVER[PHP_SELF]">
             Your Name:<input type="text" name="user" />
             <br/>
             <button type="submit" class="btn btn-primary">Say World</button>
             </form>
      _HTML_;
      ?>
      
    • 範例2 : world1.php
      <?php
           print "<h5>test</h5>";
      ?>
      
PHP 基本輸出方法
  1. 使用 echo
  2. 使用 print
  3. 使用 printf() 函數
  4. 範例:
    <?php
         echo "Hello <br />";
         echo 'World <br />';
         print "Hello2 <br />";
         print 'World2 <br />';
         printf("Hello World");
    ?>
    
PHP 註解用法
  1. 單行註解 : // or #
  2. 區塊註解 : /* */
  3. 範例 : ex6_2.php
    <?php
         echo "你愛他 <br />";
      // echo '真的嗎? <br />';
      print "他不愛你 <br />";
      /* 以下是猜的
      print '他有外遇 <br />';
      printf("你有外遇");
      */
    ?>
    
課後練習:
  1. 實作 hello.php 內容,並上傳檔案至 github 你的專案內!

PHP 語言運作概念

設定目標:
  • 了解靜動態網站運作方式
  • 了解 PHP 動態網站運作方式
  • 了解 MVC 模組運作方式

WWW 站台運作基本概念:
  • WWW 站台的運作方式:
    1. 靜態網站--圖案取自「鳥哥的私房菜」

    2. 動態網站--圖案取自「鳥哥的私房菜」

  • PHP 動態語言運作方式與 MVC 概念
    1. PHP 在 WWW 站台內運作的情形概念

    2. MVC 運作模式概念
  • 現代網站分工模式介紹
    1. 前端網頁運作
      • HTML / CSS / JavaScripts
      • Framework
    2. 後端網站運作
      • PHP / Java / Python / C++ /C
      • Framework

2021年3月3日 星期三

在 Windows 10 上安裝 Docker

設定目標:
  • 在 Windows 10 Home上安裝 Docker
  • 其它版本只要安裝 Hyper-V 元件,即可順利安裝完成!

  1. Docker 官網上,選擇 Windows 版本下載 Docker 套件!
  2. 開啟下載檔案,開始安裝流程!
  3. 安裝過程中,需要使用 WSL 2 相關元件,以及想在桌面上有捷徑可用!所以,請勾選這兩項!
  4. 顯示安裝過程!
  5. 安裝過後,需要重新開機!
  6. 重開機之後,桌面上會有一個徑捷圖示!
  7. 在通知項目清單中,提示要安裝 WSL2 項目!直接按下連結網址與 restart 按鍵!
  8. 連結網址將引導至微軟網頁!按項目步驟進行安裝即可!
  9. 以系統管理員,啟動 PowerShell !
  10. 將網頁中的指令,複製到 PowerShell 中執行!
  11. 按網頁指示,依不同版次的 windows ,執行不同的指令!
  12. 安裝後,應會自舅重新開機!
  13. 開機後,請注意查看一下工作列上的 Docker 圖示!應該是處於停止運作的狀況!
  14. 此時按滑鼠右鍵,試著重新啟動 docker ....
  15. 接下來,通知需要安裝 WSL2 Linux 核心更新套件!畫面會引導至微軟網頁!
  16. 下載檔案後,進行安裝流程!
  17. 安裝完成後的畫面!
  18. 按照網頁指示,將 WSL 版本設定在第 2 版!
  19. 設定過程中,如果有要求重新啟動系統,會出現如下畫面,記得就直接 restart !!
  20. 重新啟動系統後,即可看到工作列上的圖示,顯示執行中!