本文將介紹PHP的一些較重要的內容。
包括:
面向對象編程、正則表達式、
程序錯誤處理、XML、
AJAX、圖像處理、MySQL數據庫、
開發模式。
一、面向對象的PHP編程
和其他面向對象語言差不多,有區別的地方會指出,其他簡要介紹一下。
注:
構造函數:function __construct();
析構函數:function __destruct();
有默認的set和get方法
指向父類:parent::
指向子類:self::
//類
<?php
class Person
{
private $name;
//構造函數
function __construct(){
$name = "MrLiuQ";
}
//析構函數
function __destruct(){
echo "析構函數被調用";
}
public function set_name($name){
$this->name = $name;
}
public function get_name(){
echo "My name is ".$this->name."<br/>";
}
}
//繼承
class Worker extends Person
{
private $salary;
//構造函數
function __construct(){
$salary = 5000;
}
//析構函數
function __destruct(){
echo "析構函數被調用";
}
public function set_salary($salary){
$this->salary = $salary;
}
public function get_salary(){
return $this->salary;
}
}
$boy = new Person;
$boy->set_name("Harry Pottor");
$boy->get_name();
$girl = new Person;
$girl->set_name("Emma");
$girl->get_name();
$a_work = new worker;
$a_work->set_name('Paul');
$a_work->set_salary(3500);
$name = $a_work->get_name();
$salary = $a_work->get_salary();
echo $name."的月薪為".$salary;
?>
<?php
class Counter
{
private static $count = 0; //靜態成員變量
function __construct(){ //構造函數
echo "計數開始";
}
function __destruct(){ //析構函數
echo "計數結束";
}
static function get_count(){ //靜態成員函數
return self::$count;
}
static function counts(){
self::$count++; //注意這里靜態成員變量的使用方法,加self::
}
}
$c = new Counter();
$i = 0;
while($i<5){
Counter::counts(); //通過限定Count::直接調用靜態函數counts(),并沒有使用對象$c來調用。
$i = Counter::get_count();
echo Counter::get_count()."<br/><br/>";
}
?>
相關函數:
__construct():構造函數
__destruct():析構函數
__get():用到不存在屬性時,系統默認調用
__set():當設置不存在屬性時,系統默認調用
__call():訪問一個不存在的方法時,默認調用
__toString():將一個對象轉換成字符串
__clone():克隆一個對象時使用。
克隆:PHP默認通過引用傳遞對象。使用$obj2 = $obj1兩對象是關聯的,如果不希望產生關聯,就使用clone,克隆一個新的對象。
二、正則表達式:Regular expression
定義:是負責對字符串做解析對比,從而分析出字符串的構成,以便進一步對字符串做相關的處理。
注:正則表達式允許用戶通過使用某種特殊字符構建匹配模式,然后把匹配模式與文件中的數據、程序輸入或者Web頁面的表單輸入等目標對象進行比較,根據這些輸入中是否包含匹配模式,來執行相應的程序。
1.正則表達式的語法:
元字符:
^ :匹配指定字符串開頭的字符串
$ :匹配指定字符串結尾的字符串
. :匹配除\n之外的任何單個字符,代替任何字符
[] :匹配指定范圍內的單個字符,代替指定字符
| :在多項之間選擇一個進行匹配
\ :轉義字符
() :標記子表達式的開始和結束位置
* :匹配其左邊的子表達式0次或多次
+ :匹配其左邊的子表達式1次或多次
? :匹配其左邊的子表達式0次或1次
限定符:
{n}:表示匹配該限定符左邊字符n次
{n,}:表示匹配該限定符左邊至少n次
{n,m}:表示匹配該限定符左邊至少n次,最多m次
轉義字符:
\n :一個換行符。等價于\x0a和\cJ
\r :一個回車符。等價于\x0d和\cM
\s :任何空白字符,包括空格、制表符、換頁符等。等價于[\f\n\r\t\v]
\S :任何非空白字符。等價于[^\f\n\r\t\v]
\t :一個制表符。等價于\x09和\cI
\v :一個垂直制表符。等價于\x0b和\cK
\f :一個換頁符。等價于\x0c和\cL
\cx :由x指明的控制字符。
字符類:
[[:alpha:]] :匹配任何字母
[[:digit:]] :匹配任何數字
[[:alnum:]] :匹配任何字母和數字
[[:space:]] :匹配任何空白字符
[[:upper:]] :匹配任何大寫字母
[[:lower:]] :匹配任何小寫字母
[[:punct:]] :匹配任何標點符號
[[:xdigit:]] :匹配任何16進制數字,相當于[0-9a-fA-F]
[[:blank:]] :匹配空格和Tab,等價于[\t]
[[:cntrl:]] :匹配所有ASCII 0到31之間的控制符
[[:graph:]] :匹配所有的可打印字符,等價于[^ \t\n\r\f\v]
[[:print:]] :匹配所有的可打印字符和空格,等價于[^\t\n\r\f\v]
反義:
\W :匹配任意不是字母,數字,下劃線或漢子的字符
\S :匹配任意不是空白符的字符
\D :匹配任意非數字的字符
\B :匹配不是單詞開頭或結束的位置
//模式:舉例
^once //匹配給定模式開頭的字符串
PHP$ //匹配給定模式結尾的字符串
^Python$ //精確定位:指定字符串
b.s //這個單詞可以是bes、bis、bos....
b[eiou]s //這個單詞只匹配 bes、bis、bos、bus
b(a|e|i|o|oo)s //這個單詞匹配bas、bes、bis、bos、boos
pe* //匹配perl、peel、pet、port...
co+ //匹配come、code、cool、co...
a{3} //匹配aaa、cacaaad、aacoaaao...
a{3,} //匹配aaa、aaab、caaaaa...
a{1,3}b //匹配ab、aab、aaab...
ab* //和ab{0,}同義,a、ab、abb...
ab+ //和ab{1,}同義,ab、abb...
ab? //和ab{0,1}同義,a、ab
a?b+$ //匹配ab、abb...
a(bc)* //匹配a、abc、abcbc...
[ab] //與a|b同義,匹配a、b
[a-d] //與a|b|c|d及[abcd]同義,匹配a、b、c、d。
^[a-zA-Z_]$ //匹配所有的只有字母和下劃線的字符串。如果不加^和$,凡是含有字母和下劃線的字符都會被匹配。
^[a-zA-Z0-9_]{1,}$ //匹配所有包含一個以上的字母、數字或下劃線的字符串。
^[0-9]{1,}$ //匹配所有正數
^\-{0,1}[0-9]{1,}$ //匹配所有的整數
^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //匹配所有小數
PHP有兩大類函數支持正則表達式,
一類是POSIX擴展函數(PHP5.2之后棄用),
另一類是Perl兼容的正則表達式函數(PHP4.0后支持)。
2.POSIX擴展正則表達式函數(PHP5后棄用):
ereg() :字符串的正則匹配函數
ereg_replace() :區分大小寫的正則表達式替換
eregi() :不區分大小寫的正則表達式匹配
eregi_replace() :不區分大小寫的正則表達式替換
split() :用正則表達式將字符串分割到數組中
spliti() :用正則表達式不區分字母大小寫將字符串分割到數組中
sql_regcase() :產生用于不區分大小的正則表達式
//正則表達式匹配函數
int ereg(string $pattern, string $string [, array ®s]); //區分大小寫
int eregi(string $pattern, string $string [, array ®s]); //不區分大小寫
<?php
$arr_date = array(
'2008-06-01',
'1997-06-25',
'1996-11-29',
'2005-0x-10',
'12-12-12',
'2012-12-25 00:10:20'
);
for ($i=0; $i<5; ++$i){
$date = $arr_date[$i];
if(ereg("([0-9]){4})-([0-9]{1,2})-([0-9]{1,2})", $date , $regs)){
echo "日期字符串$date 符合'YYYY-MM-DD'格式:";
echo "$regs[1].$regs[2].$regs[3]<br/><br/>";
}else{
echo "<b>日期字符串$date 不符合'YYYY-MM-DD'格式</b><br/><br/>";
}
}
?>
//替換匹配字符串的函數
string ereg_replace(string $pattern, string $replacement, string $string); //區分大小寫
string eregi_replace(string $pattern, string $replacement, string $string); //不區分大小寫
<?php
$str = "You have a car , I have a Car , We have cARs!" //源字符串
echo "<b>替換前字符串為:</b><br/>";
echo $str;
echo "<br/>";
echo "<br/>";
$pattern = "car"; //匹配字符串
$replacement = "Apple"; //替換后字符串
$str_rpc = eregi_replace($pattern,$replacement,$str);
echo "<b>替換后字符串為:</b><br/>";
echo $str_rpc;
?>
//根據正則表達式分割字符串函數
array split(string $pattern, string $string [, int $limit]);
<?php
$str = "aaa~bbb~ccc~ddd"; //定義字符串變量
echo "字符串截取前:$str";
echo "<br/>";
echo "<br/>";
$sep_arr = split("~",$str);
echo "<b>字符串截取后:</b><br/>"; //分割字符串變量$str
echo "<pre>";
print_r($str_arr);
?>
//生成正則表達式的函數
string sql_regcase(string $string); //不區分大小正則表達式
<?php
$str = "K#V3050"
echo "<b>原字符串:</b><br/>$str"; //定義字符串變量
echo "<br/>";
echo "<br/>";
$reg_str = sql_regcase($str);
echo "<b>生成的正則表達式為:</b><br/>"; //生成正則表達式
echo $reg_str;
?>
3.PERL兼容正則表達式函數(PHP4后支持,重點):
PERL兼容正則表達式使用修正符,
所謂修正符,是指正則表達式最后的補充說明。
另外,
PERL兼容正則表達式中所有的模式前后都需要加/
修正符
i :匹配時忽略大小寫
m :除了匹配^$整個字符串開頭和結尾,還匹配其中的換行符(\n)的之后和之前
s :使原點字符(.)匹配任意一個字符同時也匹配換行符
x :模式中的空白字符除了被轉義的或在字符類中的以外完全被忽略
e :preg_replace()在替換字符串中對逆向引用作正常的替換,將其作為PHP代碼求值,并用其結果來替換所搜索的字符串
A :模式被強制為“anchored”,即強制僅從目標字符串的開頭開始匹配
D :模式中的行結束($)僅匹配目標字符串的結尾,否則包含換行符
S :為加速匹配而對其進行分析,分析一個模式僅對沒有單一固定其實字符的nonanchored模式有用
U :使“?”的默認匹配成為貪婪狀態
X :一個反斜線后面跟一個沒有特殊意義的字母被當成該字母本身
u :模式字符串被當成UTF-8
preg_grep() :返回與模式匹配的數組單元的正則表達式函數
preg_match() :進行正則表達式匹配的函數
preg_match_all() :進行全局正則表達式匹配的函數
preg_replace() :執行正則表達式的搜索和替換的函數
preg_split() :用正則表達式分割字符串的函數
//返回與模式匹配的數組單元的正則表達式函數
array preg_grep(string $pattern, array $input [, int $flag]);
<?php
$test_preg = array(
"AK47",
"163.com",
"happy new year",
"EX0000",
"007 in USA",
"abc123",
"TEST-abc-315",
"123654789",
"Euapa00!"
);
echo "<b>原數組:</b>";
echo "<pre>";
print_r($test_preg);
echo "</pre>";
$preg_arr = preg_grep("/^[A-Z].*[0-9]$/",$test_preg); //正則表達式
echo "<br>";
echo "<b>將原數組中以任意大寫字母開頭的、中間任意個字符、最后以數字結尾的字符串找出:</b>";
echo "<pre>";
print_r($preg_arr); //輸出匹配的元素
echo "</pre>";
?>
//進行正則表達式匹配的函數
int preg_match(string $pattern , string $subject [, arrayy $matches [, int $flag]]);
<?php
$str_arr = array(
"PHP 是優秀的Web腳本語言",
"Perl的文本處理功能很強大"
);
foreach($str_arr as $str){
//使用了修正符
if(preg_match("/php/i",$str)){
echo "在字符串'$str'中找到對'php'的匹配";
echo "<br/>";
echo "<br/>";
}else{
echo "在字符串'$str'中<b>未</b>找到對'php'的匹配";
echo "<br/>";
echo "<br/>";
}
}
?>
//進行全局正則表達式匹配的函數
int preg_match_all (string $pattern, string $subject, array $matches [,int $flag]);
<?php
$html = "<b>粗體字符</b><a href=index.html>可點擊的連接</a>";
preg_match_all("/(<([\w]+)[^>]*>)(.*)(<\/\\2>)/", $html , $matches);
for ($i=0;$i<count($matches[0]);$i++){
echo "匹配:".$matches[0][$i]."\n";
echo "第一部分:".$matches[1][$i]."\n";
echo "第二部分:".$matches[2][$i]."\n";
echo "第三部分:".$matches[3][$i]."\n\n";
}
?>
//執行正則表達式的搜索和替換的函數
mixed preg_replace(mixed $pattern,mixed $replacement,mixed $subject [, int $limit]);
<?php
$string = "The quick brown fox jumped over the lazy dog.";
echo "原字符串:<br/>";
echo $string;
echo "<br/><br/>";
$patterns[0] = "/quick/";
$patterns[1] = "/brown/";
$patterns[2] = "/fox/";
$replacements[2] = "bear";
$replacements[1] = "black";
$replacements[0] = "slow";
$str1 = preg_replace($patterns,$replacements,$string); //替換字符串
echo "使用函數ksort()之前字符串替換為:<br/>";
echo $str1;
echo "<br/><br/>";
ksort($patterns); //排序
ksort($replacements); //排序
$str2 = preg_replace($patterns,$replacements,$string);
echo "使用函數ksort()之后字符串替換為:<br/>";
echo $str2;
echo "<br/><br/>";
?>
//用正則表達式分割字符串的函數
array preg_split(string $pattern,string $subject [,int $limit [, int $flag]]);
//參數$limit=-1,$flag參數如下:
PREG_SPLIT_NO_EMPTY:只返回非空的部分
PREG_SPLIT_DELIM_CAPTURE:界定符模式中的括號表達式會被捕捉返回
PREG_SPLIT_OFFSET_CAPTURE:對每個出現的匹配結果同時返回其附屬的字符串偏移量。注意,這改變了返回的數組的值,使其中的每個單元也是一個數組,其中第一項為匹配字符串,第二項為它在$subject中的偏移量
<?php
$str = 'PHP language programming in Web'; //定義字符串變量
echo "<b>原字符串:</b><br/>";
echo $str;
echo "<br/><br/>";
$chars = preg_split('/ /',$str,-1,PREG_SPLIT_OFFSET_CAPTURE); //分割字符串
echo "<b>調用函數preg_split()后:</b>";
echo "<pre>";
print_r($chars);
?>
4.幾例常見的正則表達式分析:
-
實例1:檢查IP地址的正則表達式:
直接上代碼:
<?php
$arr_ip = array( //定義了一個數組
"192.168.1.100",
"-12.255.0.10",
"256.1.2.255",
"10.9c.132.69",
"255.255.255.255",
"123.0.0.0.1"
);
foreach ($arr_ip as $ip ) { //驗證數組里的IP
if (validateIp($ip)) { //驗證ip
echo "<b>$ip 是正確的IP地址</b>";
echo "<br/><br/>";
}else {
echo "$ip 不是正確的IP地址";
echo "<br/><br/>";
}
}
function validateIp($ip){ //驗證ip的函數
$iparray = explode(".",$ip);
for ($i=0; $i < count($iparray); $i++) {
if ($iparray[$i]>255) {
return (0);
}
return preg_match("/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/",$ip);
}
}
?>
-
實例2:檢查中文字符的正則表達式:
直接上代碼
<?php
$str_arr = array( //測試數組
"I am very happy",
"快樂編程快樂生活",
"PHP編程",
"1997年香港回歸",
"英語學習ABC",
"123456789"
);
$patt_ch = chr(0xa1)."-".chr(0xff); //匹配中文字符的ASCII范圍
foreach ($str_arr as $str){
echo "字符串'$str'是";
if(preg_match("/[$patt_ch]+/",$str)){ //注意在正則表達式的前后使用界定符
echo "<b>存在中文</b>";
echo "<br>";
echo "<br>";
}else {
echo "不存在中文";
echo "<br>";
echo "<br>";
}
}
?>
- 實例3:檢查Email地址的正則表達式
<?php
$str_arr = array( //測試數組
"mymail@somesite.com",
"my_mail@somesite.com",
"my-mail@somesite.com",
"my.mail@somesite.com",
"mymail@somesite.ccoomm",
"mymail@site.cn",
"mymail@@@site.com",
"mymail@site",
"MyMail@somesite.com",
"My2007@somesite.com",
"163mail_for-me777@somesite.com",
"510137672@qq.com"
);
$patt_email = "/^[_a-zA-Z0-9-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4}$/"; //驗證郵箱
foreach ($str_arr as $str){
echo "字符串'$str'是";
if(preg_match($patt_email,$str)){ //注意在正則表達式的前后使用界定符
echo "<b>合法的Email格式</b>";
echo "<br>";
echo "<br>";
}else {
echo "不合法的Email格式";
echo "<br>";
echo "<br>";
}
}
?>
-
實例4:檢查URL地址的正則表達式
直接上代碼:
<?php
$str_arr = array( //測試數組
"http://www.liubaiqi.cn",
"www.liubaiqi.cn",
"http://www.liubaiqi.cn/login.html",
"http://liubaiqi.com",
":www.liubaiqi.cn"
);
$patt_url = "/^(http:\/\/)?[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*.+$/"; //驗證URL的正則表達式
foreach ($str_arr as $str){ //遍歷數組
echo "字符串'$str'是";
if(preg_match($patt_url,$str)){ //匹配URL
echo "<b>合法的URL格式</b>";
echo "<br>";
echo "<br>";
}else {
echo "不合法的URL格式";
echo "<br>";
echo "<br>";
}
}
?>
三、PHP程序中的錯誤處理
PHP程序異常通常有3種情況:
1.語法錯誤:代碼書寫、語法錯誤
2.運行時錯誤:代碼本身沒有錯,在運行時操作時出錯
3.邏輯錯誤:最難改,程序能正常運行,但最終結果不是所期望的值
1.內置異常處理類——Exception
PHP5增加了內置的異常處理類——Exception,內置函數
getMessage():返回對錯誤的描述信息
getCode():返回錯誤代碼,以數字形式出現
getFile():返回發送錯誤的文件名
getLine():返回發送錯誤的代碼行號
getTrace():返回backtrace()錯誤
getTraceAsString():返回已格式化成字符串的、由函數getTrace()所產生的信息
__toString():產生異常的字符串信息,可以重載
現在讓我們來看一下PHP中內置異常處理類的完整代碼:
<?php
class Exception{
protected $message = 'Unknown exception'; //異常信息
protected $code = 0; //用戶自定義異常代碼
protected $file; //發生異常的文件名
protected $line; //發生異常的代碼行號
function __construct($message = null,$code = 0);
final function getMessage(); //返回異常信息
final function getCode(); //返回異常代碼
final function getFile(); //返回發生異常的文件名
final function getLine(); //返回發送異常的代碼行號
final function getTrace(); //backtrace()數組
final function getTraceAsString(); //已格式化成字符串的getTrace()信息
function __toString();; //可輸出的字符串,可重載
}
?>
2.捕獲異常的方法:
和JAVA很像,
try...catch...:異常處理的格式
throw:拋出異常
例如:
<?php
try{
$error = '拋出異常信息,并且跳出try塊<br/>';
if (is_dir('./test')) {
echo '監測到../ch16是一個目錄';
echo '<br/>';
echo '可能繼續做其他一些操作';
echo '<br/>';
echo '....';
echo '<br/>';
}else {
throw new Exception($error, 12345); //拋出異常
}
echo '上面throw異常的話,這行代碼不會執行,轉而執行catch塊<br/>';
}catch(exception $e){ //獲取異常
echo '捕獲異常:'.$e->getMessage()."<br/>錯誤代碼:".$e->getCode().'<br/>';
echo '<br/>';
}
echo '繼續執行';
?>
3.獲取異常信息的函數使用:
直接上代碼例子
<?php
$file = './var/www/html//index.html'; //指定文件地址
try{
if (is_dir($file)) { //判斷是否是目錄
echo '檢測到目錄';
}else {
//創建異常對象,錯誤信息將由Exception類的成員函數getMessage()返回
throw new Exception('未找到該目錄或文件');
}
}catch(Exception $e){
echo '捕獲異常:'.$e->getMessage();
echo '<br/><br/>';
echo '錯誤所在文件:'.$e->getFile();
echo '<br/><br/>';
echo '錯誤所在行號:'.$e->getLine();
echo '<br/>=================================<br/>';
}
echo '程序執行完畢';
?>
4.自定義的錯誤處理:myHandler()
PHP中默認錯誤處理器被自定義的錯誤處理函數myHandler()替代
<?php
set_error_handler('myHander'); //自定義錯誤處理函數
function myHander($code,$msg,$file,$line){
echo "<br/>";
echo "程序<b>$file</b>執行過程中,在第<b>$line</b>行,產生一個錯誤。";
echo "<br/>";
echo "錯誤代碼為:<b>$code</b>,錯誤的原因是:<b>$msg</b>";
}
echo $uvar; //輸出未定義變量,錯誤處理
?>
四、PHP 與 XML
XML:擴展標記語言(eXtensible Markup Language),由W3C制定
它不僅僅是一種標記語言,還是一種存儲數據的格式。
用XML可以描述標記建立數據,
現在由于JSON的優越性(解析完能轉換成非常好的數據結構,使用起來會很方便),數據解析上更多的使用JSON,
但作為初學者,還是要學習一下XML的內容。
這里參考一篇技術博客,這里關于XML和JSON解析講解的很好。
1.XML與HTML的不同:
注意:XML和HTML有些不同,
XML用來描述數據,并關注數據是什么;
而HTML用來顯示數據,它關注的是如何使數據顯示出來。
XML并不是作為HTML的替代品而出現,它們有各自的領域和價值。
2.XML實例:
下面描述一個圖書館信息的XML文檔
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<title>Learning PHP7</title>
<author>David</author>
<publisher>White Water Press</publisher>
<price>29.90</price>
</book>
<book>
<title>Learning XML</title>
<author>MrLiu</author>
<publisher>White Water Press</publisher>
<price>58.90</price>
</book>
<book>
<title>Using PERL</title>
<author>Lucy</author>
<publisher>White Water Press</publisher>
<price>17.90</price>
</book>
<book>
<title>Windous Networks</title>
<author>Paul</author>
<publisher>White Water Press</publisher>
<price>32.99</price>
</book>
<book>
<title>Fly Leaf</title>
<author>Jenny</author>
<publisher>White Water Press</publisher>
<price>19.50</price>
</book>
</books>
- 1.XML聲明:
version屬性:描述XML的版本號
standalone屬性:描述該XML文件是否和一個獨立的聲明文件(DTD)配套使用,YES表示沒有DTD,NO表示有DTD配套
encoding屬性:XML分析器支持的編碼標準,常用的是UTF-8和GB2312(簡體中文碼)
- 2.XML元素:<標記>數據內容</標記>
<國籍>中國</國籍>
<title>Learning XML</title>
- 3.標記和屬性:<標記名 屬性名="屬性取值">
<person sex="female">
- 4.處理指令:<?處理指示名 處理指示信息?>
<?cocoon-process type="sql"?>
cocoon是來自Apache軟件基金會的XML處理框架,該實例告訴cocoon,XML文檔包含一個SQL語句。
- 5.實體:
實體是文檔用來替換一些特殊標記符號的字符串。
XML和HTML中常見的實體如下:
<:代表小于符號<,less than
>:代表大于符號>,greater than
":代表一個雙引號
&apos:代表一個單引號,或撇號
&:代表一個“與”符號&
注:實體以“&”開頭,以英文“;”結束。
- 6.文件類型定義(DTD):
一個完全意義上的XML文件不僅應該是形式良好的,而且還該使用自定義標記的XML文件。定義來表示數據的標記,最常用的方法是實用文檔定義類型(Document Type Definition)DTD。
簡而言之,DTD規定了一個語法分析器為了解釋一個“有效的”XML文件所需要知道的所有規則和細節。
實例:DTD用來指定XML文檔的基本結構,在XML文件的序言部分加入一個DTD描述,加入位置在XML處理指示之后
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE 根元素名[
元素描述
]>
文件體
DTD中使用元素類型聲明(Element Type Definition,ETD)來聲明所有有效的文件元素。ETD結構如下:
<!ELEMENT 元素名 元素內容描述>
所以剛才的圖書館實例可以修改為:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 這些是圖書館中圖書的有關信息-->
<!DOCTYPE books[
<!ELEMENT books (book)*>
<!ELEMENT book (title,author,publisher,price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT price (#PCDATA)>
]>
<books>
<book>
<title>Learning PHP7</title>
<author>David</author>
<publisher>White Water Press</publisher>
<price>29.90</price>
</book>
<book>
<title>Learning XML</title>
<author>MrLiu</author>
<publisher>White Water Press</publisher>
<price>58.90</price>
</book>
<book>
<title>Using PERL</title>
<author>Lucy</author>
<publisher>White Water Press</publisher>
<price>17.90</price>
</book>
<book>
<title>Windous Networks</title>
<author>Paul</author>
<publisher>White Water Press</publisher>
<price>32.99</price>
</book>
<book>
<title>Fly Leaf</title>
<author>Jenny</author>
<publisher>White Water Press</publisher>
<price>19.50</price>
</book>
</books>
使用DTD中也可以定義屬性,格式如下:
<!ATTLIST 元素名 (屬性名 屬性類型 默認值) *>
實例:
<!ELEMENT city (#PCDATA)>
<!ATTLIST city province CDATA #REQUIRED>
這段示例XML定義了<city>元素,同時使用關鍵字ATTLIST聲明元素的屬性。屬性列表中的名稱city告訴解析器這些屬性是為元素<city>定義的。名稱province是屬性的名稱,關鍵字CDATA和#REQUIRED告訴XML解析器province屬性包含文本并且是必須的。如果是可選的,使用CDATA #IMPLIED。
3.PHP對XML的支持:
PHP5后支持符合W3C標準的DOM和SimpleXML擴展,默認情況下同時支持SAX(原生支持)、DOM、SimpleXML。
XML解析器分為兩種類型:
一種是基于樹型的解析器:將XML文檔轉換成樹型結構。提供一個API來訪問所產生數的每個元素,其通用的標準為DOM,即文檔對象模式。重點在結構,樹型結構。
二種是基于事件的解析器:將XML文檔視為一系列的事件。當一個而特殊事件發生時,默認調用開發者提供的函數處理。重點在數據,從頭到尾。
- PHP函數處理XML文檔:
//XML解析器的建立
resource xml_parser_create([string $encoding]);
//XML解析器的釋放
bool xml_parser_free(resource $parser);
//處理XML元素的函數
bool xml_set_element_handler(resource $parser,callback $start_elem_handler,callback $end_elem_handler);
//處理XML字符數據的函數
bool xml_set_character_data_handler(resource $parser,callback $handler);
//解析一個XML文檔
int xml_parse (resource $parser,string $data [, bool $is_final]);
Expat函數XML文檔實例:
//ExpatXML.php
<?php
$parser = xml_parser_create(); //初始化XML分析器
function start($parser , $elem_name,$elem_attrs){ //在一個元素開始時調用的函數
switch ($elem_name) {
case "BOOKS":
echo "<b>-- 圖書信息 --</b><br/><br/>";
break;
case "TITLE":
echo "<b>書名:</b>";
break;
case "AUTHOR":
echo "<b>作者:</b>";
break;
case "PUBLISHER":
echo "<b>出版社:</b>";
break;
case "PRICE":
echo "<b>價格:</b>";
break;
}
}
function stop($parser,$elem_name){ //在一個元素結束時調用的函數
echo "<br/>";
}
function char($parser,$data){ //當找到一個字符數據時調用該函數
echo $data;
}
xml_set_element_handler($parser,"start","stop"); //指定元素處理器
xml_set_character_data_handler($parser,"char"); //指定字符數據處理器
$fp=fopen("XMLTest.xml","r"); //打開XML文件
while($data=fread($fp,1024)){ //循環讀入XML文件中的內容
xml_parse($parser,$data,feof($fp)) or
die(sprintf("XML錯誤:%s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
xml_parser_free($parser); //釋放XML分析器資源
?>
- 使用SimpleXML處理XML
SimpleXML,名副其實,使用起來十分簡單,最適合簡單的、類似記錄的數據。
SimpleXML函數:
//載入XML文件的函數
object simplexml_load_file(string $filename [, string $class_name [,int $options]]);
<?php
if(file_exists('XMLTest.xml')){ //判斷文件是否存在
$xml = simplexml_load_file('XMLTest.xml'); //加載文件
var_dump($xml);
}else{
exit('載入文件test.xml失敗');
}
?>
//載入XML字符串的函數
object simplexml_load_strig(string $data [, string $class_name[, int $options]]);
<?php
$xml_str = "<?xml version='1.0' encoding='UTF-8'?>";
$xml_str .= "<EMAILDOCUMENT>";
$xml_str .= "<TITLE>最近在學什么</TITLE>";
$xml_str .= "<FROM>小強</FROM>";
$xml_str .= "<TO>大強</TO>";
$xml_str .= "<BODY>";
$xml_str .= "我最近在學PHP,你呢?";
$xml_str .= "</BODY>";
$xml_str .= "</EMAILDOCUMENT>";
$xml = simplexml_load_string($xml_str); //加載XML字符串
var_dump($xml);
?>
SimpleXML實例:
<?php
$xml = simplexml_load_file("XMLTest.xml"); //載入指定的XML文檔
echo "==== " . $xml->getName() . "====<br/>"; //獲取當前元素的名稱
foreach ($xml->children() as $child) {
echo "--- ".$child->getName()."---<br/>";
foreach ($child->children() as $ch) {
echo $ch->getName().":".$ch."<br/>";
}
echo "<br/>";
}
?>
- 使用PHP的DOM庫處理XML文檔
DOM是Document Object Model的縮寫。它是在瀏覽器中使用的、用JavaScript操作的W3C DOM規范。分析成DOM的樹型結構。
下面介紹如何通過DOM在PHP中處理XML文檔:
步驟如下:
1> 首先需要創建一個DOM的實例,即DOMDocument
$dom = new DOMDocument;
2>載入XML到該實例中,有兩種方法:一是從一個字符串載入,使用函數loadXML(),二是從文件載入,使用load()。
//使用字符串載入
$dom->loadXML('<string>books</string>');
//從文件載入
$dom->load('XMLTest.xml');
3>使用DOM對象的documentElement屬性可以訪問XML文檔的根元素
<?php
$dom = new DOMDocument; //1.創建DOM實例
$dom->load('XMLTest.xml'); //2.載入XML到該實例中
$root = $dom->DOMDocumentElement; //3.獲取XML文檔的根元素
?>
4>使用DOM對象的saveXML輸出XML字符串,而使用方法save()可以將XML保存為一個XML文件
<?php
$xml_str = "<?xml version='1.0'?>"; //開始下定義XML字符串
$xml_str .="<books>";
$xml_str .="<book>";
$xml_str .="<title>Harry Potter</title>";
$xml_str .="<author>J.K.Rowling</author>";
$xml_str .="<publisher>Warner Bros.</publisher>";
$xml_str .="<price>39.0</price>";
$xml_str .="</book>";
$xml_str .="</books>";
$dom = new DOMDocument;
$dom->LoadXML($xml_str); //載入定義的XML字符串
echo $dom->saveXML(); //將XML輸出到一個字符串
$dom->save("test.xml");
?>
5>使用DOM的getElementsByTagName()方法可以返回一個元素的字符數據,該函數接受一個元素名稱作為參數。
<?php
$doc = new DOMDocument();
$doc->load('XMLTest.xml'); //載入指定的XML文檔
$books = $doc->getElementsByTagName("book"); //返回book元素的數據
foreach($books as $book){ //遍歷book元素
$authors = $book->getElementsByTagName("author");
$author = $authors->item(0)->nodeValue;
$publishers = $book->getElementsByTagName("publisher");
$publisher = $publishers->item(0)->nodeValue;
$titles = $book->getElementsByTagName("title");
$title = $titles->item(0)->nodeValue;
$prices = $book->getElementsByTagName("price");
$price = $prices->item(0)->nodeValue;
echo "$title - $author - $publisher - $price";
echo "<br/>";
echo "<br/>";
}
?>
五、PHP 與 AJAX
AJAX是當今Web應用中的一種相當流行的技術,
它最大的優點是給用戶最佳的瀏覽體驗。
無論是使用Java、ruby還是PHP,都可以實現AJAX應用
注:AJAX并不完全依賴于某種服務器腳本程序,它是在瀏覽器端實現的技術
1.什么是AJAX?
AJAX,全稱:“Asynchronous JavaScript and XML”
翻譯一下,是異步JavaScript和XML
是一種創建交互式網頁應用的網頁開發技術。
其中包括:使用XHTML和CSS標準實現Web頁面,使用DOM實現動態顯示和交互,使用XML進行數據交換與處理,最后使用JavaScript綁定和處理所有數據。
AJAX將一些服務器負擔的工作下放至客戶端,利用客戶端的某些能力來處理數據,從而減輕了服務器和帶寬的負擔。
AJAX最大的優點是頁面無序刷新就可以更新頁面內容和數據,減少用戶實際等待的時間,給了用戶最佳的體驗效果。
2.AJAX的工作原理:
在AJAX之前,Web站點強制用戶進入提交、等待、頁面刷新顯示數據的流程。其中有大量的網絡請求,服務器和網絡帶寬有很大的負擔。
然而,AJAX可以在用戶單擊按鈕時,使用JavaScript和DHTML立即更新Web頁面,并向服務器發出異步請求,以執行更新或查詢數據庫。當請求返回時,就可以使用JavaScript和CSS響應更新Web頁面,而不是刷新整個頁面。最重要的時,這種速度非常快,Web站點看起來是即使響應的。
原理:關于AJAX工作原理,可以用一句話概括:通過XMLHttpRequest對象來向服務器發一部請求,從服務器獲得數據,然后用JavaScript來操作DOM從而完成頁面更新。
AJAX工作原理
缺陷:然而AJAX并不是完美的,它也有缺陷。AJAX破壞了瀏覽器的“后退”機制。即后退無法返回原先的頁面,這是一個相當大的缺陷,雖然后來有使用一個隱藏的IFRAME來重現頁面上的變更,但是成本是非常大的。
3.PHP與AJAX:
- 創建XMLHttpRequest對象(JavaScript對象):
<script language="javascript">
var xmlHttp = new XMLHttpRequest();
</script>
不同的瀏覽器使用不同的方法創建XMLHttpRequest對象,
例如,IE使用ActiveXObject,所以最好使用如下代碼,改進版:
var xmlHttp = null;
if(window.xmlHttpRequest){
xmlHttp=new xmlHttpRequest();
}else if(window.ActiveXObject){
xmlHttp=new ActiveXObject("Microsoft.xmlHTTP");
}
完整的XMLHttpRequest對象的JavaScript程序:
//AJAXTest.js
function GetXmlHttpRequest(){
var xmlHttp=null;
try{
xmlHttp = new XMLHttpRequest(); //對于Firefox等瀏覽器
}
catch(e){
try{
xmlHttp = new ActiveXObject("Msxm12.XMLHTTP"); //對于IE瀏覽器
}
catch(e)
{
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){
xmlHttp =false;
}
}
}
return xmlHttp;
}
- 發送異步請求:
先了解一下XMLHttpRequest對象的一些方法:
open(method,url[ ,async]):使用method參數所指定的方式(POST或GET)打開一個url指定的鏈接。async為true表示異步,false為同步。
setRequestHeader(label,value):在請求報頭增加一個鍵值對
send(content):JavaScript將請求和數據向服務器發送出去
getAllResponseHeaders():獲取服務器所有的HTTP響應報頭,并作為一個字符串返回
getResponseHeader(label):獲取一個有參數label指定的HTTP響應報頭
abort():用來終止當前的請求
再了解一下XMLHttpRequest對象的屬性和含義:
onreadystatechange:每次請求狀態發生改變時,會調動由該屬性保存的事件處理時間
readyState:對象狀態值,有5種選擇:0表示為初始化,1表示正在加載(loading),2表示加載完畢(loaded),3表示正在接受響應,4表示響應接受完畢(complete)
responseTest:從服務器返回的數據,以字符串形式給出
responseXML:從服務器返回DOM兼容的文檔數據對象,即XML數據對象
status:從服務器返回數字代碼,比如404(未找到)或200(一切正常)
statusText:與狀態相關的文本信息
發送異步請求的JavaScript程序:
function sendRequest(){
//獲取頁面表單的文本框name的值
var user_name = document.getElementById("name").value;
if ((user_name == null)||(user_name == "")) {
return;
}
xmlHttp = GetXmlHttpRequest();
if(xmlHttp == null){
alert("瀏覽器不支持XmlHttpRequest!");
return;
}
var url = "getUserName.php"; //構建請求的URL地址
url = url + "?name=" + user_name;
xmlHttp.open("GET",url,true); //使用GET方法打開一個到url的連接,為發出請求做準備
//設置一個回調函數,當服務器完成請求后調用
xmlHttp.onreadystatechange = updatePage;
xmlHttp.send(null); //發送請求
}
回調函數:
function updatePage(){
if (xmlHttp.readyState == 4) {
var response = xmlHttp.responseText;
document.getElementById("userInfo").value = response
}
}
完整實例:
//AJAXTest.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>ajax應用實例</title>
<script language="javascript">
var xmlHttp = null;
function GetXmlHttpRequest(){
var xmlHttp = null;
try{ //創建XMLHttpRequest對象
xmlHttp = new XMLHttpRequest();
}
catch(e){
try {
xmlHttp = new ActiveXObject("Msxm12.XMLHTTP");
}
catch (e) {
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) {
xmlHttp = false;
}
}
}
return xmlHttp; //返回XMLHttpRequest對象
}
function sendRequest(){ //發送異步請求
var prov_name = document.getElementById("province").value;
if ((prov_name == null)||(prov_name == "")) {
return;
}
xmlHttp = GetXmlHttpRequest();
if (xmlHttp == null) {
alert("瀏覽器不支持XMLHttpRequest!");
return;
}
var url = "AJAXTest.php";
url = url + "?prov=" + prov_name;
xmlHttp.open("GET",url,true);
xmlHttp.onreadystatachange = updatePage;
xmlHttp.send(null);
}
function updatePage(){ //處理服務器響應
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
var response = xmlHttp.responseText;
document.getElementById("city").innerHTML = response;
}
}
</script>
</head>
<body>
<h3>請選擇一個省(自治區):</h3>
<form action="AJAXTest.php">
<div>
<select id="province" onchange="sendRequest()">
<option value="">請選擇一個省(自治區)</option>
<option value="ah">安徽</option>
<option value="fj">福建</option>
<option value="gd">廣東</option>
<option value="js">江蘇</option>
<option value="sh">上海</option>
<option value="ln">遼寧</option>
<option value="bj">北京</option>
<option value="hb">河北</option>
<option value="hn">河南</option>
<option value="hlj">黑龍江</option>
<option value="xj">新疆</option>
<option value="xz">西藏</option>
<option value="nmg">內蒙古</option>
</select>
</div>
</form>
<div id="city">
</div>
</body>
</html>
//AJAXTest.php
<?php
$city_arr = array(
"ah"=>"合肥",
"fj"=>"福州",
"gd"=>"廣州",
"js"=>"南京",
"sh"=>"上海",
"ln"=>"沈陽",
"bj"=>"北京",
"hb"=>"石家莊",
"hn"=>"鄭州",
"hlj"=>"哈爾濱",
"xj"=>"烏魯木齊",
"xz"=>"拉薩",
"nmg"=>"呼和浩特"
);
if (empty($_GET['prov'])) {
echo '<font color="red">您沒有選擇省(自治區)</font>';
}else{
$prov = $_GET['prov'];
$city = $city_arr[$prov];
echo '所選省(自治區)省會(首府)為:'.$city;
}
?>
注意:在這個實例中,我遇到一些問題,用ajax始終無法響應,我猜測可能是html和php文件關聯上有問題,存在bug,我沒調出來。回過頭我再調。
- 一個已經實現AJAX的PHP類——xajax
xajax是一個開源的PHP類庫,它能綜合HTML、CSS、JavaScript、PHP,輕而易舉就開發出強大的、基于AJAX的Web應用。
下載xajax:官網:http://www.xajaxproject.org/
如何在PHP程序中使用xajax:
1>包含xajax庫:require_once("xajax.inc.php");
2>創建xajax對象:$xajax = new xajax();
3>注冊需要通過xajax調用的名稱:$xajax->registerFunction("myFunction");注冊函數名為:myFunction
4>編寫注冊的PHP函數,并且在函數中使用xajaxResponse對象創建向瀏覽器端返回的XML指令
5>在PHP程序輸出任何信息之前,調用xajax用于接管請求:$xajax->processRequests();
6>在頁面的<head></head>標簽之間,使用xajax生成實現AJAX應用所必須的JavaScript代碼:$xajax->printJavascript();
7>在程序中,從Javascript時間或者函數調用前面注冊的函數,例如:<button onclick="xajax_myFunction(SomeArgument);">
實例:
<?php
require_once("xajax/xajax.inc.php");
$xajax = new xajax(); //實例化xajax對象
//$xajax->debugOn(); //打開ajax調試功能
//注冊一個xajax調用的php函數名(與JavaScript中的函數名xajax_showOutput相對應)
$xajax->registerFunction("showOutput");
//編寫上面已經注冊的php函數,在此函數中用xajaxResponse對象來返回XML指令集
function showOutput(){
$testResponse = new xajaxResponse();
$testResponse->addAlert("Hello");
$testResponse2 = new xajaxResponse();
$testResponse2->loadXML($testResponse->getXML());
$testResponse2->addReplace("this","is","a","replacement");
$testResponseOutput = htmlspecialchars($testResponse2->getXML());
$objResponse = new xajaxResponse();
//使用xajaxResponse對象的addAssign方法添加XML指令
//該指令將id為submittedDiv的元素的innerHTML屬性更新為$testResponseOutput
$objResponse->addAssign("submittedDiv","innerHTML",$testResponseOutput);
return $objResponse;
}
$xajax->processRequest(); //在腳本傳送出任何東西前,xajax都要處理所有請求
?>
<html>
<head>
<meta http-equiv="content-type" content="text/html";charset="utf-8" />
<title>xajaxTest</title>
<?php
//這代碼使xajax對象可以生產所必須的JavaScript
$xajax->printJavascript("xajax/");
?>
</head>
<body>
<!--在這里調用 -->
<p><div onclick="xajax_showOutput();">單擊這里顯示響應XML</div></p>
<div id="submittedDiv">這里將被響應的XML指令所替換</div>
</body>
</html>
六、PHP 圖像處理
PHP除了開發Web應用,還可以生成圖片或對圖片進行加工處理
目前主流圖片處理庫:Grafika
GitHub地址:https://github.com/kosinix/grafika/
是基于Imagick和GD,可以用于改變圖片大小,剪裁,比較,添加水印等等功能。還有感知哈希,高級圖像過濾,繪制貝塞爾曲線等功能,非常強大。
關于Grafika:可以參考這篇博客,寫的非常完整詳細。
本章主要講述較底層的GD擴展庫的方法和使用:
- GD擴展庫主要函數:
imagecreatefromgif():用來從指定的GIF文件取出圖像
imagegif():創建一個GIF圖像
imagecreatefrompng():從指定PNG文件取出圖像
imagepng():創建一個PNG圖像
imagecreate():新建一個基于調色板的圖像
imagecreateturecolor():返回一個黑色圖像的標識符
imagecolorallocate():創建一個由RGB顏色指定的圖像
imagefill():用指定的顏色填充圖像
imageline():用指定顏色畫出一條線段
imagestring():在圖像上顯示一個字符串
imagettftext():用TrueType字體向圖像寫入文本
imageSX/imageSY():分別用來去的圖像寬度和高度
imagettfbbox():用來去的使用TrueType字體的文本范圍
imagealphablending():用來設定圖像的混色模式
imagecopyresized():用來復制部分圖像并調整大小
imagecopyresampled():重采賦值部分圖像并調整大小
getimagesize():獲取圖像屬性
- 步驟:
1>建立畫布
2>在畫布上繪制形狀或書寫文本
3>輸出最終的圖片
4>清空繪圖資源
- 圖像的建立:
//1.生成圖像:
<?php
$width = 200; //寬度
$height = 200; //高度
$img = imagecreatetruecolor($width,$height)or die("不支持GD圖像處理"); //創建圖像
imagepng($img);
imagedestory($img);
?>
//2.設定圖像顏色:
<?php
$width = 200; //寬度
$height = 200; //高度
$img = imagecreatetruecolor($width,$height)or die("不支持GD圖像處理"); //創建圖像
$bg_color = imagecolorallocate($img,255,0,0); //設置圖像標識符所描述圖像的顏色
imagefill($img,0,0,$bg_color); //改變圖像的顏色
imagepng($img);
imagedestory($img);
?>
//3.在圖像上繪制直線:
<?php
$width = 200; //寬度
$height = 200; //高度
$img = imagecreatetruecolor($width,$height)or die("不支持GD圖像處理"); //創建圖像
$line_color = imagecolorallocate($img,255,255,255); //設置圖像標識符所描述圖像的顏色
imageline($img,0,40,200,40,$line_color); //繪制直線
imageline($img,0,260,200,260,$line_color); //繪制直線
imagepng($img);
imagedestory($img);
?>
//4.在圖像上輸出文字:
<?php
$width = 200; //寬度
$height = 200; //高度
$img = imagecreatetruecolor($width,$height) or die("不支持GD圖像處理"); //創建圖像
$line_color = imagecolorallocate($img,255,255,255); //設置圖像標識符所描述圖像的顏色
imageline($img,0,40,200,40,$line_color); //繪制直線
imageline($img,0,260,200,260,$line_color); //繪制直線
imagestring($img,5,0,60,"It's time to learn PHP!",$line_color); //顯示文字
imagepng($img);
imagedestory($img);
?>
//5.在圖像中顯示中文字符:
<?php
$width = 200; //寬度
$height = 300; //高度
$img = imagecreatetruecolor($width,$height) or die("不支持GD圖像處理"); //創建圖像
$line_color = imagecolorallocate($img,255,255,255);
$font_type = "C://WINDOUS//Fonts//SIMLI.TFF"; //獲取TrueType字體,采用隸書字體
//"西游記"3個字的16進制字符
$cn_char1 = chr(0xE8).chr(0xA5).chr(0xBF);
$cn_char2 = chr(0xE6).chr(0xB8).chr(0xB8);
$cn_char3 = chr(0xE8).chr(0xAE).chr(0xB0);
//"吳承恩著"4個字的16進制字符
$cn_str = chr(0xE5).chr(0x90).chr(0xB4).chr(0xE6).chr(0x89).chr(0xBF).chr(0xE6).chr(0XE6).chr(0X81).chr(0XA9);
$cn_str .=" ".chr(0xE8).chr(0x91).chr(0x97);
imageline($img,0,40,200,40,$line_color); //繪制直線
imageline($img,0,260,200,260,$line_color); //繪制直線
//豎排顯示"西游記"3字
imagettftext($img,30,0,10,80,$line_color,$font_type,$cn_char1);
imagettftext($img,30,0,10,120,$line_color,$font_type,$cn_char2);
imagettftext($img,30,0,10,160,$line_color,$font_type,$cn_char3);
//橫排顯示“吳承恩著”4字
imagettftext($img,15,0,90,254,$line_color,$font_type,$cn_str);
imagepng($img);
imagedestroy($img);
?>
- 圖片的處理:
//1.打開已存在的圖片:
<?php
$img = imagecreatefromjpeg("tower.jpg"); //打開指定的圖片文件
Imagejpeg($img);
Imagedestroy($img);
?>
//2.獲取圖片的相關屬性:
<?php
$img = imagecreatefromjpeg("tower.jpg"); //打開指定的圖片文件
$x = imageSX($img);
$y = imageSY($img);
echo "圖片tower.jpg的寬為:<b>$x</b> pixels";
echo "<br/>";
echo "<br/>";
echo "圖片tower.jpg的高為:<b>$y</b> pixels";
Imagejpeg($img);
Imagedestroy($img);
?>
//3.對圖片加水印效果:
<?php
function makeImageWaterMark($image,$pos,$water_text,$font_size,$color){
$font_type = "C://WINDOWS//Fonts//cour.ttf";
if (!empty($image) && file_exists($image)) {
$img_info = getimagesize($image);
$g_w = $img_info[0]; //取得背景圖片的寬
$g_h = $img_info[1]; //取得背景圖片的高
switch($img_info[2]){ //取得背景圖片的格式
case 1:
$img = imagecreatefromgif($image);
break;
case 2:
$img = imagecreatefromjpeg($image);
break;
case 3:
$img = imagecreatefrompng($image);
break;
default:
die("圖片格式錯誤");
}
}
else{
die("需要加水印的圖片片不存在!");
}
//取得使用 TrueType字體的文本范圍
$temp = imagettfbbox(ceil($font_size*2.5),0,$font_type,$water_text);
$w = $temp[2] - $temp[6];
$h = $temp[3] - $temp[7];
if (($g_w<$w)||($g_h<$h)) {
echo "需要加水印的圖片的大小比水印文字區域小,無法生成水印";
return;
}
//設置4種水印效果位置:0和默認是隨機位置,1為頂端居左,2為中部居中,3為底端居右
switch($pos){
case 0:
$pos_x = rand(0,($g_w - $w));
$pos_y = rand(0,($g_h - $h));
break;
case 1:
$pos_x = 0;
$pos_y = 0;
break;
case 2:
$pos_x = ($g_w - $w)/2;
$pos_y = ($g_h - $h)/2;
break;
case 3:
$pos_x = $g_w - $w;
$pos_y = $g_h - $h;
break;
default:
$pos_x = rand(0,($g_w - $w));
$pos_y = rand(0,($g_h - $h));
break;
}
imagealphablending($img,true); //設置圖像混色模式
if(!empty($color)&&(strlen($color)==7)){
$R = hexdec(substr($color,1,2));
$G = hexdec(substr($color,3,2));
$B = hexdec(substr($color,5));
}
else{
die("水印文字顏色格式不正確!");
}
$text_color = imagecolorallocate($img,$R,$G,$B);
imagettftext($img,$font_size,0,$pox_x,$pos_y,$text_color,$font_type,$water_text);
switch($img_info[2]){
case 1:
imagegif($img,$image);
break;
case 2:
imagejpeg($img,$image);
break;
case 3:
imagepng($img,$image);
break;
default:
die("不被支持格式的圖片!");
}
Imagedestroy($img);
}
if(isset($_FILES)&&!empty($_FILES['userfile'])&&$_FILES['userfile']['size']>0){
$uploadfile = "./".time()."_".$_FILES['userfile']['name'];
if (copy($_FILES['userfile']['tmp_name'],$uploadfile)) {
makeImageWaterMark($uploadfile,2,"Photo by Macc",16,"$43042A");
echo "<img src=\"".$uploadfile."\"border=\"0\">";
}
else{
echo "文件上傳錯誤!<br/>";
}
}
?>
<html>
<head>
<title>GDTest.php</title>
</head>
<body>
<form enctype="multipart/form-data" method="POST">
選擇上傳圖片:<input name="userfile" type="file">
<input type="submit" value="上傳">
</form>
</body>
</html>
//4.生成已有圖片的縮略圖:
<?php
$img_name = "tower.jpg";
$src_img = imagecreatefromjpeg($img_name);
$ow = imagesx($src_img); //取得原圖的寬
$oh = imagesy($src_img); //取得原圖的高
$nw = round($ow*200.0/$ow); //計算新圖的寬度
$nh = round($oh*200.0/$oh); //計算新圖的高度
$desc_img = imagecreate($nw,$nh); //建立新圖
imagecopyresized($desc_img,$src_img,0,0,0,0,$nw,$nh,$ow,$oh); //生成縮略圖
imagejpeg($desc_img);
imagedestroy($desc_img);
imagedestroy($src_img);
?>
//5.使用imagecopyresampled函數做縮略圖:
<?php
$img_name = "tower.jpg";
$percent = 0.2;
$src_img = imagecreatefromjpeg($img_name);
$ow = imagesx($src_img); //取得原圖的寬
$oh = imagesy($src_img); //取得原圖的高
$nw = $ow * $percent //計算新圖的寬度
$nh = $oh * $percent //計算新圖的高度
$desc_img = imagecreate($nw,$nh); //建立新圖
imagecopyresampled($dec_img,$src_img,0,0,0,0,$nw,$nh,$ow,$oh); //生成縮略圖
imagejpeg($desc_img);
imagedestroy($desc_img);
imagedestroy($src_img);
?>
- 實例:生成帶有底紋的數字驗證碼圖片
<?php
$img_height = 60;
$img_width = 20;
for ($tmpa=0; $tmpa <4 ; ++$tmpa) {
$nmsg[$tmpa]=dechex(rand(0,15)); //生成隨機數,并轉成十六進制,作為驗證碼
}
$aimg = imagecreate($img_height,$img_width); //生成圖片
imagecolorallocate($aimg,255,255,255); //圖片底色
$black = imagecolorallocate($aimg,0,0,0); //定義需要的黑色
//用黑色的矩形把圖片包圍
imagerectangle($aimg,0,0,$img_height-1,$img_width-1,$black);
//下面的代碼生成底紋,其實就是在圖片上生成的一些符號
for ($i=0; $i < 100; ++$i) {
//使用*行號作為底紋,為了使底紋看起來雜亂無章、五顏六色,需要一個個地生成,同時使位置、顏色、大小都用隨機數
imagestring($aimg,1,mt_rand(1,$img_height),mt_rand(1,$img_width),"*",
imagecolorallocate($aimg,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255)));
}
//生成驗證碼,同樣的道理,驗證碼一個個地輸出到圖片上,同時其位置、顏色、大小都用隨機數
for($i=0;$i<count($nmsg);++$i){
imagestring($aimg,mt_rand(3,5),$i*$img_height/4+mt_rand(1,10),mt_rand(1,$img_width/4),
$nmsg[$i],imagecolorallocate($aimg,mt_rand(0,100),mt_rand(0,150),mt_rand(0,200)));
}
header("Content-type:image/png");
imagepng($aimg);
imagedestroy($aimg);
?>
七、PHP 與 MySQL
Web程序中的各類數據需要靠數據庫存儲,只有在數據庫配合的基礎上,PHP才能發揮其最大功效。
MySQL本身并不是數據庫,他只是用來創建、維護、管理數據庫的計算機軟件。
1.MySQL數據庫的基本操作
//windous 登錄MySQL命令
mysql -u user_name -p password -h host
//退出MySQL
quit
exit
//創建數據庫
create database database_name;
//刪除數據庫
drop database database_name;
//表的建立
create table Users(
UserId int unsignd not null,
UserName varchar(50) not null,
Gender char(6) not null defaultale',
RegTime date not null;
);
// varchar是變長字符串,在1-255之間
// char指定長度,不足空格補
//建立索引:INDEX
create table books(
id int not null,
name varchar(40) not null,
price = decimal(3,2),
index idx(id)
);
//特殊索引,主鍵
create table users(
id int not null primary key,
name varchar(30),
create_time date
);
//查看某個數據庫中所有表的命令
show tables
//查看某個表的結構
use database
describe table_name
//插入數據
insert into users(id,name,created_time) values (1,'MrLiuQ','2017-07-22 10:18:00');
insert into users values(1,'MrLiuQ','2017-07-22 10:18:00');//省略字段名
insert into users set id=2,name='David',create_name='2017-07-22 10:18:00';
//查詢數據
SELECT name,created_time AS ct FROM users;
//條件查詢
SELECT *FROM users WHERE name='MrLiuQ';
SELECT *FROM users WHERE created_time>'2017-07-22 10:18:00';
SELECT *FROM users WHERE name='MrLiuQ'->AND created_time>'2017-07-22 10:18:00';
SELECT *FROM users WHERE name='MrLiuQ'->OR created_time>'2017-07-22 10:18:00';
//更新數據
UPDATE users SET name'Lily Cameron' WHERE id=3;//成功后,表users中id為3的用戶名被修改為Lily Cameron
//刪除數據
DELETE FROM users WHERE name='Lily Cameron';
//對查詢結果做排序
SELECT *FROM users WHERE created_time >'2017-07-22 10:18:00'->ORDER BY id DESC;//ASC表示升序,DESC表示降序。
//對查詢結果做分組
SELECT city FROM users GROUP BY city;
//對查詢結果做限定
SELECT name,city FROM users ORDER BY name LIMIT 4;//返回前4條信息
2.MySQL的數據類型
INT:整數值。UNSIGNED INT指定無符號整數值
DECIMAL:指定數字值的精度和范圍
REAL:浮點數值
CHAR:定長字符類型
VARCHAR:變長字符串,在1~255之間
TEXT:文本類型
DATE:日期值
TIME:時間值
DATETIME:MySQL支持,存放日期和日期類型
3.MySQL函數
COUNT():統計表中記錄個數或這列中值的個數
MAX():返回某列中的最大值
MIN():返回某列中的最小值
SUM():指定列的值求和
AVG():計算指定列的平均值
LENGTH():字符串的長度
SUBSTRING():截取子字符串
YEAR():返回指定日期的年份
UNIX_TIMESTAMP():返回一個UNIX時間戳
DATE_FORMAT():將一個日期格式化
NOW():返回MySQL服務器系統的當前日期和時間
//計算表中總共有多少條記錄
SELECT COUNT(*) FROM users;
//計算特定值的個數
SELECT COUNT(*) FROM users WHERE name LIKE 'J%';
//計算列最大值
SELECT MAX(salary) AS max_salary FROM emp_salary;
//計算列最小值
SELECT MIN(salary) AS max_salary FROM emp_salary;
//求和
SELECT SUM(salary) AS total_salary FROM emp_salary;
//求平均
SELECT AVG(salary) AS avg_salary FROM emp_salary;
//字符串長度
SELECT LENGTH('string in MySQL');
//截取指定長度字符串
SUBSTRING(string,pos,len);
//獲取一個UNIX時間戳
SELECT UNIX_TIMESTAMP() AS timestamp;
//格式化輸出日期
SELECT DATE_FORMAT<created_time,'%Y年%m月%d日'> AS DATE-> FROM users WHERE id=3;
4.用PHP操作MySQL數據庫
步驟:
=> 建立數據庫的鏈接
=> 選擇要使用的數據庫
=> 創建SQL語句
=> 執行SQL語句
=> 獲取SQL執行結果
=> 處理數據結果集
=> 關閉與數據庫的鏈接
//連接數據庫
mysql_connect(string $server,string $user_name,string $password,[bool $new_link,int $client_type]);
mysql_pconnect(...) //長久鏈接
$conn = mysql_connect('locolhost','root','user_pass');
//關閉數據庫
bool mysql_close([resource $link]);
//執行SQL語句
mysql_query(string $sql);
//處理查詢結果集的函數
mysql_affected_rows(); //取前一次MySQL操作記錄行數。
mysql_fetch_row($result); //從查詢結果集中返回一行數據。$result是執行mysql_query()之后返回的資源標識符
mysql_fetch_array($result,$type); //從結果集中返回一行作為關聯數組
mysql_fetch_assoc($result); //該函數只將結果集作為關聯數組返回
//獲取字段信息
object mysql_fetch_field($result [, int field_offset]);
//選擇一個數據庫
mysql_select_db($database);
//取得結果集的行目數
mysql_num_rows($result);
//返回最近一次MySQL操作產生的錯誤文本信息
mysql_error();
//PHP程序
<?php
$host = 'localhost'; //定義服務器
$user_name = 'root'; //定義用戶名
$password = 'admin'; //定義密碼
$conn = mysql_connect($host,$user_name,$password); //連接MySQL
if(!$conn){
die('數據庫連接失敗:'.mysql_error());
}
mysql_select_db('test'); //連接數據庫
$sql = 'select id,name,city from users';
$result = mysql_query($sql) OR die("<br/>ERROR:<b>".mysql_error()."</b><br/><br/><br/>產生問題的SQL<br/>".$sql); //獲取查詢結果
if($result){
echo 'SQL語句:'.$sql.'<br/>已經成功執行!';
$num = mysql_num_rows($result); //調用mysql_num_row()獲取SELECT語句查詢
echo '<br/>該SQL語句查詢到<b>'.$num.'</b>行數據';
}
if($num = mysql_num_rows($result)) //判斷SELECT語句查找到的行數
{
$row = mysql_fetch_array($result); //mysql_fetch_array()將結果集中的一行作為數組返回
echo '<pre>'; //格式化輸出
while($row = mysql_fetch_array($result,MYSQL_ASSOC))
{
print_r($row); //輸出每行數據
}
}
mysql_close($conn);
?>
八、PHP 與 MVC開發設計模式
1.什么是MVC模型?
MVC是Model_View_Control的縮寫,簡單的講Model是程序的數據模型,View是程序的視圖界面,Control是程序的流程控制處理部分。
大部分的操作由Control完成,主要有兩個動作:
1.根據用戶界面(view)的操作完成對程序數據(model)的更新
2.將程序數據(model)的改變及時反映到用戶界面(view)上
優點:程序結構更加清晰,代碼穩定性更強,有利于提高開發效率,有利于控制開發速度。
2.MVC模型的核心組成:
1.模型(Model——M):既然是數據模型,那么它就攜帶著數據,通常還會將業務規則的實現放進模型,這意味著模型不僅僅是數據的容器,還是數據的監控者
2.視圖(View——V):Web而言,視圖就是用戶看到的HTML頁面,從程序角度來說,視圖負責生成用戶界面,通常根據數據模型中的數據轉化成HTML輸出給用戶
3.控制器(Controller——C):負責協調整個應用程序的運轉,對于WEB而言,就是接受瀏覽器的請求,并決定調用哪個模型構件去處理瀏覽器端發出的請求,然后確定用哪個視圖來顯示模型處理返回的數據。
3.PHP開發中的模板技術:
在PHP開發中,模板不可或缺。本節將首先介紹模板的基本概念和其在PHP程序中的用法,然后一個優秀的模板引擎——Smarty。
- 什么是模板?
模板是一組插入了HTML的PHP腳本,或者說是插入了PHP腳本的HTML文件 - 在PHP程序中使用模板:Demo
//temp.html
<html>
<head>
<title>{pagetitle}</title>
</head>
<body>
{greetings}
</body>
</html>
//temp.php
<?php
$template_file = "temp.html"; //模板文件
$fs = fopen($template_file,"r"); //打開文件
$content = fread($fs,filesize($template_file)); //讀取文件內容
fclose($fs);
$content = print_page($content,"pagetitle","模板應用");
$page = print_page($content,"greetings","您好,這個頁面由模板生成");
echo $page;
function print_page($temp_c,$temp_v,$str_c){
return preg_replace("/\{".$temp_v."\}/",$str_c,$temp_c);
}
?>
- Smarty模板引擎:
PHP中有很多模板引擎可供選擇,Smarty是一款易于使用且功能強大的PHP模板引擎
Demo:
//Smarty.tpl
{* 這里是Smarty模板的注釋*}
<html>
<head>
<title>{$page_title}</title>
</head>
<body>
大家好,我是{$name}模板引擎,歡迎大家在PHP程序中使用{$name}。
</body>
</html>
{*模板文件結束*}
//Smarty.php
<?php
include("./Smarty/libs/Smarty.class.php"); //包含Smarty類文件
$smarty = new Smarty(); //建立Smarty類的實例$smarty
$smarty->template_dir = "./templates"; //設置模板目錄
$smarty->compile_dir = "./templates_c"; //設置編譯目錄
$smarty->left_delimiter = "{"; //設定左右邊界符為{},Smarty推薦使用<{}>
$smarty->right_delimiter = "}";
$smarty->assign("name","Smarty"); //進行模板變量替換
$smarty->assign("page_title","Smarty的使用"); //進行模板變量替換
$smarty->display("Smarty.tpl"); //編譯并顯示位于./templates下的Smarty.tpl模板
?>
4.其他常見的基于MVC的PHP框架簡介:
- Laravel:在國外非常流行,國內用的少,適用于大項目。官網:http://laravel.com
- thinkphp:適用于小項目,國產,在中國用的比較多。官網:http://thinkphp.cn
- CodeIgniter:適用于中小型項目。一個小巧、但功能強大的、由PHP編寫的、基于MVC的Web應用開發框架。同時也是經過Apache/BSD-style開源許可授權的免費框架。官網:http://codeigniter.org.cn
- CakePHP:命令行代碼生成工具讓開發者可以快速生成應用程序框架。官網:http://www.cakephp.org
- Zend Framework: PHP官方的框架,由Zend公司負責開發和維護。官網:http://framework.zend.com
- FleaPHP:一款國產Web開發框架,官網:http://www.fleaphp.org
尾篇:總結了15天,終于寫完了,存在很多不足,需要去完善
各位大神如果發現那里寫的不對,可以私信我。
我會細心修改,
謝謝!