3、PHP進階學習

46. 進制php

十六進制:html

<?php
echo 0x123;		// 前面加0x,表示十六進制
echo 1*pow(16, 2)+2*pow(16, 1)+3*pow(16, 0);		// 十六進制轉十進制
?>

十進制:web

<?php
echo 123;			// 十進制
echo 1*pow(10, 2)+2*pow(10, 1)+3*pow(10, 0);		// 十進制實際算法
?>

八進制:算法

<?php
echo 0123;		// 前面加0,表示八進制
echo 1*pow(8, 2)+2*pow(8, 1)+3*pow(8, 0);		// 八進制轉十進制
?>

二進制:數組

<?php
echo 0b10100110;		// 前面加0b,表示二進制
echo 1*pow(2, 7)+1*pow(2, 5)+1*pow(2, 2)+1*pow(2, 1);		// 二進制轉十進制
?>

N進制轉十進制公式:
例:N進制的 abc瀏覽器

a * pow(N, M1) + b * pow(N, M2) + c * pow(N, M3)緩存

ps: N爲幾進制;M爲數字所在的位置,從右往左數,從0開始,如a是第2位,則M1爲2,依次類推。安全

題外話:
進制還有一種狀況,叫作進制循環,就比如一個圓形重力稱,假設最大值爲60,當指針顯示指向60時,有多是60,也有多是0。
那麼應該怎麼看進制循環呢?
0b11111111 是理解成255,仍是-1,取決於程序。
服務器

課題案例:svg

三隻老鼠,8瓶藥,其中有一瓶有毒,怎麼一次性查出那瓶藥有毒?
提示:N只老鼠有2^n種可能狀態組合。

答:

0	0	1		=》	1
0	1	0		=》	2
0	1	1		=》	3
1	0	0		=》	4
1	0	1		=》	5
1	1	0		=》	6
1	1	1		=》	7
0	0	0		=》	0

4,5,6,7 給老鼠1
2,3,6,7 給老鼠2
1,3,5,7 給老鼠3

若	1,2死,3活,則6號瓶有毒
	1,3死,2活,則5號瓶有毒
	1死,2,3活,則4號瓶有毒
	,,,
	依次類推

46. 位運算

位運算,是針對字符上的位來運算。
把位的 0/1 當成 假/真,針對每一個位上的邏輯運算,就是位運算。

$a = 0b00001101;
$b = 0b00000011;

操做			二進制		名稱			描述
$a & $b		0b00000001	按位與		同真則真,不然爲假
$a | $b		0b00001111	按位或		同假則假,不然爲真
$a ^ $b		0b00001110	按位異或		不一樣爲真,相同爲假
~ $a		0b11110010	按位取反		將 $a 中爲 0 的位設爲 1,爲1的位設爲0。
$a >> $b	0b00000001	右移			把$a的位數向右移動$b位,每一次移動至關於除以2
$a << $b	0b01101000	左移			把$a的位數向左移動$b位,每一次移動至關於乘以2

47. 錯誤報告設置

PHP腳本有N多等級的錯誤,如:fetal error、notice、warning。
有時候咱們不想要顯示報錯信息,特別是生產環境,由於報錯信息可能會暴露服務器的相關信息,會給系統形成重大損失。所以,在開發環境和生產環境設置錯誤等級報告。

error_reporting(0);							// 不報告任何錯誤
error_reporting(E_ALL);						// 報告全部錯誤
error_reporting(E_ALL ^ E_NOTICE);			// 不報告notice
error_reporting(E_ALL & ~ E_NOTICE);		// 不報告notice

48. 浮點數並不精確

某些小數在10進制下,是有限的,轉成其它進制要無限循環。所以,損失一些精度,致使浮點數的計算和數學上結果不一致。
例:

<?php
// 直接打印八進制
$a = 01.1;
var_dump($a);

// 經過計算: 1 * pow(8, 0) + 1 * pow(8, -1)
var_dump(1 * pow(8, 0) + 1 * pow(8, -1));
?>

49. 邏輯運算的短路特性與運算符優先級

短路特性,是指因某一部分條件不經過,後續的條件不用再作判斷,直接跳過。

各個運算符優先級,以下:

優先級 結合方向 運算符 描述
1 非結合 clone、new clone和new
2 [ array()
3 非結合 ++ / - - 遞增/遞減運算符
4 非結合 ~ - (int) (float) (string) (array) (object) (bool) @ 類型
5 非結合 instanceof 類型
6 右結合 ! 邏輯操做符
7 * / % 算術運算符
8 + - . 算術運算符和字符串運算符
9 <<>> 位運算符
10 非結合 < 、<= 、> 、>=、 <> 比較運算符
11 非結合 ==、!=、===、!== 比較運算符
12 & 位運算符和引用
13 ^ 位運算符
14 | 位運算符
15 && 邏輯運算符
16 || 邏輯運算符
17 ? : 三元運算符
18 =、+=、-=、*=、/=、.=、%=、&=、|=、^=、 <<=、>>= 賦值運算符
19 and 邏輯運算符
20 xor 邏輯運算符
21 or 邏輯運算符
22 , 多處用到
<?php
$a = FALSE;
if($a && $b){
	// todo
}
// 點評:
// 若 $a 爲假,又用而且計算,結果爲假,程序並不會去判斷 $b 的真假。
?>
<?php
$a = TRUE;
if($a || $b){
	// todo
}
// 點評:
// 若 $a 爲真,又用或計算,結果爲真,程序並不會去判斷 $b 的真假。
?>

課題案例:

$a = 3;
$b = 5;
if($a = 5 || $b = 7)
{
     $a++;
     $b++;
}
echo $a ,’ ', $b;


手寫出$a,$b的值?


50. 文件管理系統
使用PHP代碼實如今瀏覽器讀取資源文件。使用函數:opendir()、closedir()、readdir()

index.php

<?php
header('Content-Type: text/html;charset=utf-8');
$path = '.';

if(isset($_GET['dir'])){
	$path = $path .'/'. $_GET['dir'];
}else{
	$_GET['dir'] = '';
	$path .= $_SERVER['REQUEST_URI'];
}
echo $path;
$dh = opendir($path);
if($dh == FALSE){
	echo '打開出錯';
	exit();
}

$list = array();
while(($item = readdir($dh)) != FALSE){
	$list[] = $item;
}
closedir($dh);
?>

<html>
	<head>
		<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
	</head>
	<body>
		<h1>文件管理系統</h1>
		<table>
			<tr>
				<td>序號</td>
				<td>文件名</td>
				<td>操做</td>
			</tr>
			<tr>
			<?php
				foreach($list as $k => $v){
					echo "<tr>";
					echo "<td>$k</td>";
					echo "<td>$v</td>";
					echo "<td>";
					if($v == '.' || $v == '..'){
						echo '<a href="index.php?dir='. $_GET['dir'] . $v .'/">瀏覽</a>';
					}else{
						if(is_dir($path .'/'. $v)){
							echo '<a href="index.php?dir='. $_GET['dir'] . $v .'/">瀏覽</a>';
						}else{
							echo '<a href="/'. $_GET['dir'] .'/'. $v .'">查看</a>';
						}
					}
					echo "</td>";
					echo "</tr>";
				}
			?>
			</tr>
		</table>
	</body>
</html>

51. 遞歸

遞歸,簡單來講就是,函數調用函數自己。

<?php
// 求n之內的全部數相加
function sum($a){
	if($a == 1)
		return 1;
	return $a + sum($a - 1);
}
echo sum(100);
?>
<?php
// 無限級遞歸
function reclass($data = array(), $pid = 0, $level = 0, $pname = 'parentid'){
	$level++;
	foreach($data as $v){
		if($v[$pname] == $pid){
			$v['level'] = $level;		// 查詢等級
			$newdata[] = $v;
			$tmp = reclass($data, $v['id'], $level, $pname);	// 進入遞歸
			if($tmp){
				$newdata = array_merge($newdata, $tmp);	// 將數組合並
			}
		}
	}
	if(isset($newdata)){
		return $newdata;
	}
}
?>

52. 遞歸技巧

假設函數已經完成,須要作跳出處理。

<?php
// 遍歷指定目錄下的文件及文件夾,以樹型展現
function printdir($path, $level = 1){
	$dh = opendir($path);
	while(($row = readdir($dh)) != FALSE){
		if('.' == $row || '..' == $row){
			continue;
		}
		
		echo '|' , str_repeat('-&nbsp;', $level) , $row , '<br>';
		
		$tmp = $path .'/'. $row;
		if(is_dir($tmp)){
			printdir($tmp, ++$level);
		}
	}
	closedir($dh);
}
$path = '.';
printdir($path);
?>

53. 遞歸與靜態變量

staic 特色:在第一次函數調用聲明以後存在,且不隨函數結束而結束,當函數再次調用時,能夠直接利用上次的結果。

<?php
function foo(){
	static $a = 10;
	$a++;
	return $a;
}

echo foo();		// 11
echo foo();		// 12
echo foo();		// 13
?>
<?php
// 對一個多維數組裏面的數字進行求和運算

function sum($arr){
	static $sum = 0;
	foreach($arr as $v){
		if(is_array($v)){
			sum($v);
		}else{
			$sum += $v;
		}
	}
	return $sum;
}

$arr = array(1, 2, 3, array(4, array(5, 6, array(7, 8))));
echo sum($arr);		// 36
?>

54. 遞歸練習

  1. 一個多維數組,若是單元值爲數字,則把原來值修改成原來的2倍。
    如:array(1, 2, ‘b’, array(3, ‘c’, array(4, 5)));
    變成 array(2, 4, ‘b’, array(6, ‘c’, array(8, 10)));

    // 在作POST、GET安全遞歸轉義時用到

  2. 遞歸建立級聯目錄
    如給定多個目錄 /a/b/c/d/e/,要求建立目錄e,發現找不到目錄a,後面沒法繼續。須要能遞歸建立。

    // 項目中常常按 年/月/日 這種格式建立目錄,並存在上傳文件

  3. 遞歸刪除目錄
    如,給定 目錄a,要把a目錄及全部下級目錄所有刪除

    // 後臺管理系統中,會批量刪除某個目錄

  4. 給定以下分組,完成無限極分類
    array(
    array(‘id’ => 1, ‘area’ => ‘北京’, ‘pid’ => 0),
    array(‘id’ => 2, ‘area’ => ‘河北’, ‘pid’ => 0),
    array(‘id’ => 3, ‘area’ => ‘保定’, ‘pid’ => 2),
    array(‘id’ => 4, ‘area’ => ‘易縣’, ‘pid’ => 3),
    array(‘id’ => 5, ‘area’ => ‘海定’, ‘pid’ => 1),
    )

55. IP、域名、DNS、host概念

IP,是給每一個鏈接在互聯網上的主機分配的一個32位地址,理論上有2^32個

域名,因爲IP地址基於數字,不方便記憶,因而便用域名來代替IP地址,域名是一個IP地址的「面具」

DNS,用於記錄IP地址和域名之間映射關係的服務

host,本地的域名IP映射

客戶端輸入域名,向服務器發出請求,首先會到DNS系統進行域名解析,DNS會返回對應的IP地址給客戶端,客戶端再用此IP地址向服務器發出請求。 瀏覽器通常都有DNS緩存,訪問過一次的域名會將其IP地址緩存到瀏覽器中,方便下次訪問。 若是在host中配了域名到ip的映射,就不會走DNS,而是直接走host。本地優先級最高。