PHP與MySQL程式設計 學習筆記 第三章 PHP基礎

吃著火鍋x唱著歌發表於2020-10-25

PHP可將程式碼嵌入到HTML頁面中,要讓程式碼完成任務,必須把頁面傳遞給PHP引擎進行解釋,但Web伺服器並不傳遞所有頁面,只傳遞具有特定檔案擴充套件標識(一般為.php)的頁面,即使只傳遞某些頁面,效率也很低下,因為每一行都可能是一個php命令,都要處理,因此引擎需要一種確定頁面哪部分是php程式碼,可通過以下方式界定PHP程式碼:
1.預設語法:

<?php
    echo "<p>Some dynamic output here</p>";
?>

2.短標籤:

<?
    print "This is another PHP example.";
?>

短標籤使用比較方便,但為了再分發的php軟體不應使用,因為該特性可能會在php.ini中被禁用。

啟用短標籤語法時,如想快速輸出一些動態文字,可使用短路語法:

<?="This is another PHP example.";?>
// 與下面形式的語句等價
<? echo "This is another PHP example."; ?>
<?php echo "This is another PHP example."; ?>

3.歷史上某些編輯器處理php採用的轉義語法時存在問題,因此php還支援另一種主流的界定形式:

<script>
    print "This is another PHP example";
</script>

4.Microsoft ASP頁面使用預定於的字元模式將靜態內容和動態內容分開,如果你想繼續使用這種語法時使用:

<%
    print "This is another PHP example";
%>

這種形式的界定符很少被使用,PHP 5.3.0開始已不再支援這種語法。

在一個頁面中,php程式碼與非php程式碼可多次交替出現。前面php塊中的變數都能被記住並由後面的塊使用。

註釋方法:
1.單行C++語法:

<?php
    // 註釋
    echo "aa";
?>

2.單行shell語法:

<?php
    # 註釋
    echo "aa";
?>

phpDocumentor是一個能將嵌入在原始碼中的註釋轉換為易讀的格式(HTML、PDF)的開源專案。它的做法是解析一個應用程式原始碼,從中搜尋被稱為DocBlock的特殊註釋,它可用於對一個應用中的所有程式碼加註釋,包括指令碼、類、函式、變數等,其中包含人可讀的解釋如作者名、程式碼版本、函式返回值等資訊。
3.多行C語法:

<?php
    /* 
       註釋1
       註釋2
    */
    echo "aa";
?>

向瀏覽器輸出資料的方法:
1.print語句:
在這裡插入圖片描述

<?php
    print("<p> aaa.</p>");
    print "<p>aaa.<\p>";
?>

雖然該函式正式語法要求使用括號把引數括起來,但也可以省略括號,因為技術上講,print不是一個函式,而是一個語言結構。

該函式的返回值總是1。
2.echo語句:
在這裡插入圖片描述
函式原型說明它可以接受多個引數,但沒必要使用該特性:

<?php
    $a = "a";
    $b = "b";
    echo $a, " and ", $b;
    echo "$a and $b";    // 同上,但更簡潔
?>

echo()和print()相比,echo()稍快一點,因為它不用返回值,但速度差異很小,可認為選擇哪個函式只是程式設計風格的問題。
3.printf()語句:
在這裡插入圖片描述
可將靜態文字和動態資訊清晰地分到兩個不同的部分組合起來,便於維護,並且還能控制動態資訊的格式,如型別、精度、對齊方式、位置。

printf("a integer %d.", 100);

%d是佔位符,被稱為型別指示符,d指示該位置上放一個整數值,即後面的100,如果傳入的是浮點數,則會去掉小數部分取整;如果傳入的是字串"one hundred",會輸出0,但如果傳入字串"123food",則會輸出123。
在這裡插入圖片描述
%.2f表示小數點後保留兩位。
4.sprintf():與printf功能相同,但它將輸出賦給字串,而非直接呈現到瀏覽器。

$v = -2.10;
echo $v;    // 輸出-2.1

$v = sprintf("%.2f", $v);
echo $v;    // 輸出-2.10

標量資料型別能表示單項資訊:
1.布林值:以數學家喬治·布林的名字命令,他是資訊理論創始人之一。只支援兩個值TRUE或FALSE,也可用非0值表示TRUE。
2.整型:不包含小數部分的數:

42    // 十進位制
0755    // 八進位制
0xC4E    // 十六進位制

所支援的最大整數與平臺有關。
3.浮點型:也稱為單精度數(float)、雙精度數(double)、實數。包含小數部分:

3.14
3.0
8.7e4    // 87000

4.字串:單引號或雙引號界定的連續字元序列。PHP將其視為陣列,可通過陣列偏移法訪問特定的字元:

$color = "maroon";
$parser = $color[2];    // 該變數為r

複合資料型別可用於將多個項聚集起來,表示為一個實體:
1.陣列:有索引的資料值集合,每個陣列索引(也稱為鍵)引用一個對應的值。php也支援多維陣列。
2.物件:物件必須顯式地宣告,宣告其屬性和行為在類中進行:

class Appliance {
    private $_power;
    
    function setPower($status) {
        $this->_power = $status;
    }
}

$blender = new Appliance;

以上定義了名為Appliance的資料結構。

在這裡插入圖片描述
講浮點數轉換成整數時,小數部分直接去掉。

標量資料型別可將一個非array值轉化成array:

$a = 1;
$a = array($a);    // $a現在是一個陣列,其中只包含一個1

$b = [1, 2, 3];
$b = array($b);    // $b不變

任何標量型別都能轉換為物件,結果是該變數成為了物件的一個名為scalar的屬性:

$a = "a";
$obj = (object)$a;

print($obj->scalar);    // 列印出"a"

但如果是複合變數轉換成物件,如果是物件,則不變,如果是陣列,則其鍵轉換為屬性名,對應值轉換為屬性值。

整數和字串相加時字串會轉換為整數。

字串轉換為整數時會將字串開頭數字轉換為數字而忽略後面的非數字內容,字串開頭的空格、製表符被忽略。字串轉浮點數時也類似。可以識別科學計數法表示的數字。

gettype函式可獲取變數的型別:
在這裡插入圖片描述
其返回值有array、boolean、double、integer、object、resource、string、unknown type。

settype函式將變數轉換為特定型別:
在這裡插入圖片描述
type可取值為array、boolean、float、integer、null、object、string,轉換成功返回true。

確定變數型別的函式:
在這裡插入圖片描述
引數型別mixed表示可以是各種型別。

name可以是array、bool、float、integer、null、numeric、object、resource、scalar、string。

如果引數var屬於該型別,則返回true。

字串中可使用$使用變數,如想輸出$,需要\轉義。

識別符號是變數、函式等各種使用者自定義物件的名字,它有以下規則:
1.必須以字母或下劃線開頭,且只能含數字、字母、下劃線、127~255的其他ASCII字元組成。
2.區分大小寫。
3.長度任意。
4.不能與php預定義識別符號相同。

變數是具有名字的記憶體位置,其中存有資料。

變數總是以$開頭,後跟一個表示變數名的識別符號。

php中不需要顯式宣告變數,其宣告和賦值可以同時進行,但最好所有變數都應當在使用前宣告,最好帶有註釋。

按值賦值每個變數都擁有表示式賦給它的一個副本,如果希望兩個變數指向一個副本,需要通過引用賦值(php 4中引入):

$color = "Hello";    // 按值賦值

$value1 = &$color;    // 引用賦值
$value2 =& $color;    // 引用賦值的另一中語法

宣告變數的位置影響其訪問範圍,即作用域:
1.區域性變數:函式中宣告的變數,只能在函式中被訪問到,退出函式時,該變數及其值會被撤銷。
2.函式引數:與區域性變數類似。
3.全域性變數:可在程式的任何位置被訪問到,如果想訪問,需要顯式地在函式中將其宣告為全域性變數:

$somevar = 15;

function addit() {
    global $somevar;
    $somevar++;
    echo "$somevar";
}

addit();    // 輸出16

如果省略函式中全域性變數的宣告:

$somevar = 15;

function addit() {
    $somevar++;    // 報錯,沒有這個區域性變數
    echo "$somevar";
}

addit();

如果去掉global關鍵字,相當於沒有賦值的區域性變數,隱式地被初始化為0。

另一種使用全域性變數的方法是使用$GLOBALS陣列:

$somevar = 15;

function addit() {
    $GLOBALS["somevar"]++;
    echo "$somevar";
}

addit();    // 輸出16

4.靜態變數:在函式退出時不會丟失值,再次呼叫函式時還可繼續使用該值:

function keep_track() {
   static $count = 0;
   $count++;
   echo "$count\n";
}

keep_track();    // 輸出1
keep_track();    // 輸出2
keep_track();    // 輸出3

它對於遞迴函式來說很有用。

php提供了很多預定義變數,包含在9個預定義陣列中,可在執行指令碼的任何位置訪問,提供了與使用者當前會話、作業系統、本地操作環境等有關的資訊。而php會建立部分變數,變數的可用性和值取決於作業系統和Web伺服器:

foreach ($_SERVER as $var => $value) {
    echo "$var => $value\n";
}    // 僅輸出部分預定義變數

$_SERVER中包含很多有用的資訊,如’REMOTE_ADDR’表示使用者ip,'HTTP_USER_AGENT’表示使用者的瀏覽器和作業系統資訊。而我測試時由於使用的是命令列方式執行,所以沒有這兩個變數。

使用預定義陣列必須先在php.ini中啟用track_vars,PHP 4.03中,它總是啟用的。

各個預定義變數陣列,它們都是超級全域性變數:
1.$_SERVER:包含由Web伺服器建立的資訊,提供了伺服器和客戶配置及當前請求環境的有關資訊。其中的變數數量不固定,一般可找到CGI 1.1(www.w3.org/CGI)規範中定義的變數,包括:
(1)'HTTP_REGERER':引導使用者到達當前位置的頁面URL。
(2)'REMOTE_ADDR':客戶ip地址。
(3)'REQUEST_URI':URL的路徑部分,當URL是http://www.a.com/dir1/dir2/index.html時,路徑部分為/dir1/dir2/index.html。
(4)'HTTP_USER_AGENT':使用者的作業系統、瀏覽器相關資訊。
2.$_GET:包含使用get方法傳遞的引數的有關資訊,如請求http://www.a.com/index.html?cat=apache$id=157,相當於給_GET陣列這樣賦值:

$_GET['cat'] = apache;
$_GET['id'] = 1157;

3.$_POST:包含使用者用post方法傳遞的引數有關資訊,如以下表單:
在這裡插入圖片描述
就可以通過目標指令碼subscribe.php使用:
在這裡插入圖片描述

與$_GET一樣,預設,$_POST是訪問POST變數的唯一方式。
4.$_COOKIE:儲存了通過HTTP cookie傳遞到指令碼的資訊,這些cookie一般是以前通過呼叫setcookie設定的。
5.$_FILE:包含通過POST方法向伺服器上傳的資料有關資訊,它是二維陣列,第一個下標是表單的檔案上傳元素名,第二個下標是五個預定義下標之一:
(1)$_FILE['upload-name']['name']:從客戶端向伺服器上傳的檔名。
(2)$_FILE['upload-name']['type']:上傳檔案的MIME型別,該變數是否被賦值取決於瀏覽器功能。
(3)$_FILE['upload-name']['size']:檔案大小,以位元組為單位。
(4)$_FILE['upload-name']['tmp_name']:上傳後,將該檔案移動到最終位置前的臨時名。
(5)$_FILE['upload-name']['error']:上傳的狀態碼,它的取值如下:
①:UPLOAD_ERR_OK:上傳成功。
②:UPLOAD_ERR_INI_SIZE:檔案大小超出了upload_max_filesize指令的最大值。
③:UPLOAD_ERR_FORM_SIZE:檔案大小超出了MAX_FILE_SIZE隱藏表單域引數(可選)指定的最大值。
④:UPLOAD_ERR_PARTIAL:檔案只上傳了一部分。
⑤:UPLOAD_ERR_NO_FILE:上傳表單中沒有指定檔案。
6.$_ENV:提供伺服器的環境資訊,如:
1.'HOST_NAME':伺服器主機名。
2.'SHELL':系統SHELL。

php還支援$GLOBALS$_REQUEST超級變數,後者記錄get、post、cookie等方法傳遞給指令碼的變數,這些變數的順序不依賴於他們在傳送指令碼中出現的順序,而是依賴於variables_order配置指令指定的順序。而前者可認為是超級全域性變數的超集包含全域性作用域內的全部變數。但最好不要使用這兩個,這樣不安全。
7._SESSION:包含於會話變數有關的資訊,註冊會話資訊可在整個網站中引用這些資訊而無需通過get或post顯式傳遞資訊。

$recipe = "spaghetti";

$$recipe = "& meatballs";    // 將串賦值給名為spaghetti的變數

echo "$recipe $spaghetti";    // 輸出spaghetti& meatballs
echo "$recipe $$recipe";    // 輸出spaghetti& meatballs

常量是程式執行中無法修改的值,可使用define函式定義:

在這裡插入圖片描述
第三個引數為true時,後面對此常量的引用將不分大小寫。

define("PI"3.141592);

printf("The value of pi is %f", PI);    // 常量引用時不需要美元符

$pi2 = 2 * PI;
printf("pi doubled is %f", $pi);

一旦定義了常量就不能重新定義或取消定義。常量是全域性的,可在指令碼任何位置引用。

在這裡插入圖片描述
php中有XOR表示布林異或。

雙引號括起的字串中的變數和轉義序列(如\n換行)都會得到相應的解析。

<?php
    $output = "a\nb";
    echo $output;
?>

以上程式碼的換行會被瀏覽器視窗忽略,但如果檢視原始碼,會發現它是兩行輸出,將資料輸出到文字檔案中也是分兩行。
在這裡插入圖片描述
在這裡插入圖片描述
單引號括起來的字串不會解析其變數和轉義序列,但單引號可以被轉義。反斜線也可以被轉義,因為反斜線可以當作轉義符使用,也可以當作普通字元使用。

在串中嵌入表示複雜型別的變數時,不太容易看出來哪些串的哪些部分是靜態的,哪些是動態的,可通過大括號界定變數:

$arr  = [1,2,3];

print("a s{$arr[1]}s");    // 輸出a s2s
print("a s$arr[1]s");    // 輸出a s2s

heredoc語法在輸出大量文字時比較好用,它用兩個相同識別符號界定字串:

print(<<<text
    aaaaaa
    bbbbbb
    cccccc
text
);

開始和結束識別符號必須相同。此例中是text。開始識別符號前需要三個左尖括號。其中的所有變數和轉義序列都得到解析,但其中的雙引號不需轉義。結束識別符號必須在一行的開始處,且前面不能有空格或多餘的字元,開始識別符號同行的後面。也不能有空格或多餘字元。

處理大量內容,或希望不轉義引號時可用heredoc。

$arr  = <<<text
    "aaaaaa"
    bbbbb
    cccccc
text ;

$s = (string)$arr;    // 將它轉換為字串型別時,引號依然正常

nowdoc類似於heredoc,但它不會解析其中的變數,也不用轉義其中的特殊字元,它的語法與heredoc唯一的不同是將heredoc的開始識別符號加上單引號。它是php 5.3.0中引入的。

php的if、while、for、foreach、switch有另一種語法,即將前大括號改為冒號,後大括號改為endif、endwhile、endfor、endforeach、endswitch。但已經計劃在未來的版本中棄用。

php中elseifelse if都能用。

switch可看作ifelse組合的一種變體,常用於將某變數與大量的值對比。break規則與C++中相同。

由於php的switch語句對型別無限制,比較浮點型時,也會出現問題:

$a = 0.2;

switch($a + 0.1) {
    case 0.3:
        print(0.3);    // 不被輸出
        break;
}

switch的型別無限制。

foreach可提取陣列中每個鍵值對,直到獲得所有項,其語法有兩種形式:

foreach (array_expr as $value) {    // 只獲取值
    statement
}

foreach (array_expr as $key => $value) {    // 獲取鍵值對
    statement
}

使用goto:

<?php
    for($count = 0; $count < 10; ++$count) {
        $randomNumber = rand(1,50);

        if ($randomNumber < 10) {
            goto less;
        }
    }

less:
    echo "Number less than 10: $randomNumber";

include()語句將在其被呼叫的位置判斷幷包含一個檔案(其中可以含一系列預定義的函式和配置變數,此時一般將該檔案include到php指令碼頂部),效果相當於將該檔案的資料複製到該語句所在位置:

include("/path/to/filename");
include "/path/to/filename";    // 相當於上一句

如果include出現在if等條件語句後,則需要將其用花括號括起來:

<?php
    if (expression) {
        include('filename');    // 必須有花括號
    }

但我測試時(php 7)不加花括號也行。

在被include的檔案中也要有php定界符。

被include的檔案中中的所有程式碼會繼承其呼叫者位置處的變數作用域。

如果啟用了allow_url_fopen,還可在include語句中引用一個遠端檔案。如果檔案所在伺服器指出php,通過傳遞必要的鍵值對,類似於get請求,所包含檔案中的變數也會得到解析:
在這裡插入圖片描述
include_once作用與inclde相同,但它會首先驗證是否已經包含了該檔案,如果已經包含了,則不會再次執行包含檔案操作:

include_once("檔案路徑");

require與include相似,書上說require即使放在if語句為假的部分也能包含指定檔案,但我測試時(php 7)判斷為假的if語句中是不能包含該檔案的。

只有啟用allow_url_open時,才能在require中使用url。

require在出錯時,指令碼將停止執行,而include出錯時,指令碼將繼續執行。常見的錯誤是引用的路徑錯誤。

require_once確保指令碼只被包含一次。有時修改了所包含檔案中的變數後,會由於再次包含原來的檔案而覆蓋被修改的變數;重複包含檔案會使其中的函式名產生衝突。

相關文章