Posted by : Dylandy Chang 2013年1月27日 星期日


==================================================================

# 前言:

> 話說,我已經有一大段時間沒有碰 PHP 了,印象中是從大一的網際網路概論之後就沒有認真的

> 讀過與寫過 PHP所以趁此機會把 PHP 重新學習與掌握一下,也藉此分享一下心得,

> 希望各位也能從我的心得中學習到一些東西,如果有什麼不對的地方歡迎指正

> 記得大一的時候,剛看到 PHP 好像看到什麼毒蛇猛獸的感覺,喔天阿!這東西好困難、好可怕,
> 對於沒寫過程式的人來說,這樣的動態語言,真的是有點太過於抽象了,現在經過了一年多了時間,
> 回過頭來看 PHP 卻有種豁然開朗的感覺,要說簡單嗎? 其實也不然,要說難嗎?其實也不然,
> 掌握了一些關鍵的要點以後,學習 PHP 變得輕鬆許多。

==================================================================


先把以前學過 PHP 的經驗放在一邊,假設自己完全沒看過這個語言,第一次看到 PHP 程式碼的時候,會有什麼想法?
  • 喔!他有標籤,那他一定是 HTML 的一部份吧,這充其量只能是腳本吧,不算是一門語言吧,寫不出什麼大東西。
  • 唔,從語法上看起來跟 C 有點像,但是好像又有哪裡不一樣,得仔細研究一下。
沒錯,PHP 在剛創造出來的時候,的確是為了擴充 HTML 的不足,所發明的一種腳本語言,但是隨著時間的演進,PHP 不斷的在進步,
他已經可以作為一個普通的語言存在。

=================== 動態語言的介紹====================================

最近幾年的時間,動態語言在業界被重視的程度大大的提高,像是 Python 、Ruby 、JavaScript 甚至是 PHP ,都讓工程師們玩出了許多

不同的花樣,為什麼這些動態語言會有這麼大的魅力呢?首先,跨平台性,這些語言都有一個很大的特徵,不論在什麼樣的平台下基本上都可以

順利的運行,不論是最常見的微軟 Windows 也好 、蘋果的 Mac 也好、工程師常用的 Linux 也好,甚至是行動裝置上都可以順利的運行,

豐富的跨平台性,讓這些語言獲得工程師的青睞,工程師只要把其中一個語言學的透徹,那麼他在職場上就會很有競爭力,那麼回過頭來看,

為什麼這些語言會有這麼強的跨平台性呢?說到跨平台性,我們不得不回過頭來看以往跨平台性高的老祖宗們,大家最熟悉的 C 語言、Java

這兩種語言分別用了兩種不同的方式實現了跨平台的效果,C 語言是透過在不同平台上的編譯器,每次都將原始碼重新編譯成適合這個平台的

程式執行檔,看起來似乎很方便,但是編譯的過程其實並不是哪麼的通用的,對於使用者來說,編譯程式是一個複雜又難懂的過程,所以 Java 

使用了另外一種不同的方式來達到相同的效果,那就是虛擬機器 JVM,透過虛擬機器的使用,每個使用者只要將編譯過的程式透過虛擬機器就可以執行了,

而開發人再針對各個不同的平台撰寫不同的虛擬機器,這樣就可以確保程式在每個平台上跑起來會完全相同了,而這樣的想法,影響了後面許多程式的發展,

知名的圖形化開發程式 Python 以及近年因為 Rails 又重新被大家找回來的 Ruby 都是類似的例子,這樣的風潮持續了一段時間,工程師們突然把

目光放到了網路的程式語言上面,為什麼呢?如果從跨平台性上來看,顯然網頁的程式語言也有相當高的跨平台性,只要在平台上安裝了瀏覽器,那麼

就可以瀏覽到幾乎相同的結果,所以開始了最近的 HTML 5 網頁技術發展,JavaScript 和 PHP 又重新回到大家的目光,快速的增加內容和改版,讓

這兩個語言也進入了主流的動態語言的行列。

======================================================================

以下我會從 4 點來討論 C 語言和 PHP 之間的異與同,希望各位讀完這篇文章以後可以基本看的懂 PHP 的文件:
  • 變數的宣告
  • 函式宣告
  • 陣列
  • 物件導向程式設計概念
#變數宣告:
C 語言是一種強型別的語言,而 PHP 卻是一種弱型別的語言,用較為通俗的說法即是:

在 C 語言裏面,當我們想要宣告一個變數的時候,我們要考慮很多東西,這個變數在這個地方應該是什麼用法:
  • 是數字呢?還是字元呢?
  • 數字的話,是整數就好了呢?還是需要小數?
這樣的方式,讓編譯器在編譯程式的時候速度會快的多,而程式的執行效率理論上也會較為良好,但是近年來,許多的程式並不走這個方向

紛紛朝著弱型別來前進,為什麼呢?最近的程式語言都標榜著對開發者友善的開發,以往我們都非常的考慮機器如何,以機器的角度去編寫程式,

讓我們程式寫起來非常的痛苦,轉個角度思考,為什麼我們要這麼痛苦呢?在宣告變數的時候就告訴編譯器這東西是變數,那就好了阿,以下我舉一些例子,

大家就可以了解其中的差別了。
  • 在 C 語言中宣告變數是這樣的:
    • int numb = 0;
    • char name = "John"; 
  • 而同樣的變數在 PHP 中的宣告方式是這樣的:
    • $numb = 0;
    • $name = "John";
從上面的例子我們可以看出,在開發者的角度來看這兩個變數其實沒有那麼大的差別的,可能大家還沒辦法體會到那種概念,這麼說好了,

C 語言的變數宣告就像是用不同的容器裝不同的東西:水就是要用杯子裝,書本要放書櫃上,看似合理,實際上確很煩瑣,

而 PHP 的變數宣告概念則不同,他像是搬家時候的大箱子,我們可以把任何的東西都放到這個箱子裏面,當我們有需要的時候再從箱子裡拿出東西就好了

所以在效率上當然 C 語言會比較好,但是從開發人的角度上,喔,那差的可不是一星半點。



#函式宣告:
在以往我們撰寫 C 語言程式的時候,每當要定義一個函式的時候,我們有幾件事情需要去做的:
  • 在程式的開頭加上 prototype 表示我程式裏面這樣的函式,他長的樣子是這個樣子。
  • 要注意這個函式是否要回傳值,如果要那麼回傳值的型別是什麼,傳入函式的引數要什麼樣類型的,需要什麼樣的型別。
和剛剛討論到的變數相同,PHP 把型別的判斷取消掉了,而且依據剛剛所提到的「讓開發者更容易開發程式」的觀念,PHP 把 prototype 取消掉了,

讓開發人專注的在函式本身的邏輯上,不需要為了語法和格式煩惱,以下我們看個例子:

  • C 語言的函式是這樣的:
    • prototype :
      • void PrintArray( int[ ] );
    • 函式本體:
                         void PrintArray( int input[ ] ){
                                  int i;
                                  for( i = 0 ; i != '\n' ; i++ ){
                                         printf( "%d" , input[ i ] );
                                    }
                           }
  • 而 PHP 的函式是這樣的:
              function  PrintArray( $input ){
                     for( $i = 0 ; $i != '\0' ; $i++ ){
                         echo $input[ $i ];
                     }
               }

從這個簡短的例子,可以看出雖然架構上看起來差不多,但是整體來說,卻簡短很多,更容易理解函式的內容。

#陣列
陣列的部份有比較多的東西和 C 語言不同:
  • 宣告時附值的方式:
    • C 語言中的宣告方式如下:
      • int Str01[ 5 ] = {  '1' , '2' , '3' , '4' , '5' };
    • PHP 中的宣告方式比較特別:
      • $Str01 = array( '1' , '2' , '3' , '4' , '5' ); 
  • 常常我們並不曉得我們需要的陣列有多大,而需要動態配置陣列的大小,C 語言中並沒有提供這樣的功能,如果我們仍然想要的話,可以硬幹出類似這樣的東西:
    • char* symbol = ( char* ) malloc ( input * sizeof ( char ) );
      所以若是有要動態的使用連續的記憶體空間,使用C 語言的話,使用 Linked list 會是比較好的選擇
  • PHP 中有提供動態配置方式,我們在使用的時候非常的簡單:
    • $symbol = array( );
    • 使用的時候就只要:
                                for( $i = 0 ; $i < 10 ; $i++ ){
                                        $symbol[ $i ] = a;
                                  }

                              >>  $symbol[ 0 ] = a;
                                    $symbol[ 1 ] = a;
                                    ...
  • 除了動態配置陣列大小之外,PHP 也有一個有趣的陣列宣告方式,稱為:關聯式陣列
    • 以往我們在 C 語言中陣列的 index 只能使用數字,而且一定得是大於或等於零的整數,這樣的限制雖然讓編寫程式變得簡單,
    • 但是對於語義的了解 ,及程式為的維護、易讀性上就大大的打了折扣,所以 PHP 才會有關聯式陣列的產生。
    • 想像一個表格,每一欄都有不同的名稱,我們只要將資料放到相關的位置就可以了:
                  $StuNum = array( 'Class01' => "40" , 
                                              'Class02' => "41",
                                              'Class03' => "30"
                                              );

                  echo $StuNum[ Class01 ];
            OUTPUT >>  40

多維陣列也是 PHP 有特色的地方,在 C 語言中我們宣告二維陣列,我們都知道是陣列的 entry 是陣列,但是我們用想像的方式去讓自己了解,
但是 PHP 就把這個概念給延伸到了程式碼之中:
             C 語言:
                 int Str02[ 3 ][ 3 ]; 

            PHP:
                $Str02 = array(
                                     array( '1' , '2' , '3' ),
                                     array( '4' , '5' , '6' ),
                                     array( '7' , '8' , '9' ) );

 這樣的可以讓程式在讀的時候更為容易,我們可以更容易的用表格的方式來取得我們想要的 entry ,對於程式設計師來說,相對於 C 語言,那是友善的多了。

#物件導向程式設計的概念

在 C 語言中,其實並沒有物件導向的概念,所以我對於我們來說就是學習物件導向的概念:

我們為了更方便的撰寫程式,會把一些程式碼打包成為一個物件,透過和物件的互動,我們可以完成我們想要的任務。

可以想像一下,我們想要讓我們的產品音樂,所以我們去買了一台 CD 播放器(類別 Class),我們會需要 CD 來讓播放器有可播放內容(屬性 property) ,而我們為了聽音樂則需要

CD 播放器的播放功能(方法 Method),而我們想要開發新的功能時候,但是並不想要把原有的功能放棄,我們使用了原有的播放器,但是加上我們自己的功能成為新的播放器(繼承 

extends),如此一來,我們在寫程式的時候就不用自己去建構大量的基礎,就好像程式書籍上有名的「自己造輪子」的提問。

下面是一個簡短的範例:

<?php

$object = new Son;     //使用 new 這個關鍵字來宣告一個變數,而這個變數來使用 Son 這個物件
$object -> test( );
$object -> test2( );


Class Dad{                                                                     // 使用 Class 關鍵字宣告一個類別,以建立一個物件
       function test( ){                                                              //在 Class 裏面的 function 稱之為 Method  
              echo   " [ Class Dad ] I am your father  <br/>";
       }
}       

Class Son extends Dad{       // 使用 extends 關鍵字可以讓此 Class 繼承原 Class 的所有 Method 不需重新再寫
      function test( ){
             echo " [ Class Son ] I am Luke <br/>";          // 繼承後的子 Class 可以用同樣的名稱來改寫 Method 
       }
      function test2( ){
             parent::test;                       
// 若仍希望保留原本父 Class 的功能,可以用 parent 關鍵字將此功能賦與給自定義的新 Method
      }
}

?>


OUTPUT:

[ Class Son ] I am Luke
[ Class Dad ] I am your father
                           

Leave a Reply

Subscribe to Posts | Subscribe to Comments

技術提供:Blogger.

- Copyright © 迪蘭帝的聊天室 -Metrominimalist- Powered by Blogger - Designed by Johanes Djogan -