一、php練習題
1.1 求數組的和以及數據的平均值。
代碼如下:
<?php
$num = 0;
$arr = 0;
$arr = [1,3,4,3,2,1];
foreach($arr as $key => $value) {
$num+=$value;
}
echo '和是:'.$num.'<br/>';
echo '平均值是:'.$num/count($arr).'<br/>';
?>
效果:
可以使用number_format(數字,精確到小數點後幾位)
來格式化到小數點後面幾位。
例:
<?php
$num = 0;
$arr = 0;
$arr = [1,3,4,3,2,1];
foreach($arr as $key => $value) {
$num+=$value;
}
echo '和是:'.$num.'<br/>';
echo '平均值是:'.number_format($num/count($arr), 1).'<br/>';
?>
效果:
1.2 數組翻轉。
代碼如下:
<?php
$arr=[1,2,3,4,5];
for($i = 0, $j = count($arr)-1; $i < $j; $i++, $j--) {
[$arr[$i], $arr[$j]] = [$arr[$j], $arr[$i]];
}
print_r($arr);
?>
效果:
1.3 遍歷二維數組
例:
<?php
$arr=[
[1,2,3,4],
[5,6,7,8]
];
for($i=0; $i<count($arr); $i++) {
for($j=0; $j<count($arr[$i]); $j++) {
echo $arr[$i][$j], ' ';
}
echo '<br/>';
}
?>
效果:
1.4 循環輸出1-100。
循環輸出1-100,其中3的倍數輸出A,5的倍數輸出B,15的倍數輸出C。
此題必須先判斷能被15整除的數,因爲如果先判斷3的倍數那麼將不會出現C,因爲能被15整除的數都能被3整除。
例:
<?php
for($i=1; $i<=100; $i++) {
if ($i%15 == 0) {
echo 'C ';
}
elseif ($i%3 == 0) {
echo 'A ';
}
elseif ($i%5 == 0) {
echo 'B ';
}
else {
echo $i.' ';
}
}
?>
效果:
1.5 打印水仙花數
例:
<?php
for($i=100; $i<=999; $i++) {
$a = (int)($i/100); // 百位數
$b = (int)($i%100/10); // 十位數
$c = $i%10; // 個位數
if ($i== pow($a, 3) + pow($b, 3) + pow($c, 3)) {
echo $i, '<br/>';
}
}
// pow(數值,數值指數)
?>
效果:
1.6 打印100以內的斐波那契數
斐波那契數的原理:一個數等於前面兩個數之和。
<?php
$num1=1;
$num2=1;
echo $num1, ' ', $num2, ' ';
while (true) {
$num3 = $num1 + $num2;
if ($num3 > 100) {
break;
}
echo $num3, ' ';
$num1 = $num2;
$num2 = $num3;
}
?>
效果:
二、作用域
2.1 全局變量
在函數外面。
例如:
<?php
$num=10;
function fun() {
echo $num;
}
echo $num;
fun();
?>
效果:
報錯了,函數內部不會去全局去找。如果我就要在函數裏面去找全局變量,可以使用超全局變量
2.2 局部變量
在函數裏面,默認情況下,函數內部是不會去訪問函數外部的變量,不像js,js局部找不到就會去全局變量去找。
2.3 超全局變量
可以在函數內部和函數外部訪問。超全局變量有如下:
利用超全局變量修改:
<?php
$_POST['num']=10;
function fun() {
echo $_POST['num'];
}
fun();
?>
效果:
可以利用$GLOBALS輸出全局變量:
<?php
$num=10;
function fun() {
echo $GLOBALS['num'];
}
fun();
?>
效果:
還可以如下關鍵字寫法:
<?php
$num=10;
function fun() {
global $num; // 將全局變量的$num的地址保存到引入到函數內部。
echo $num;
}
fun();
?>
效果:
2.4 常量沒有作用域
例:
<?php
define('PI', 3.14);
function fun () {
echo PI;
}
fun();
echo '<hr/>';
function fun1 () {
define('NUM', 6.28);
}
fun1();
echo NUM
?>
效果:
2.5 靜態變量
靜態變量一般指的是靜態局部變量,靜態變量只初始化一次。
例:
<?php
function fun() {
$num=10;
$num++;
echo $num, '<br/>';
}
fun();
fun();
?>
效果:
普遍局部變量,函數沒調用一次就初始化一次,不會進行疊加。
採用靜態局部變量(靜態變量只初始化一次):
<?php
function fun() {
static $num=10;
$num++;
echo $num, '<br/>';
}
fun();
fun();
?>
效果:
常量和靜態變量的異同點:
- 常量和靜態變量都只初始化一次;
- 常量初始化完成後不能改變值,靜態變量初始化後可以改變值。
- 常量沒有作用域的區分,靜態變量是局部作用域。
2.6 匿名函數的use( )
默認情況下,函數內部訪問不到函數外部的變量,但在匿名函數中,可以通過use將外部變量引入匿名函數中。
例:
<?php
$num=10;
$fun = function () {
echo $num;
};
$fun();
?>
效果:
這個時候就可以使用ues(),將外部的變量給引入:
<?php
$num=10;
$fun = function () use ($num) {
echo $num;
};
$fun();
?>
效果:
2.7 總結在局部作用域中訪問全局變量。
- 使用超全局變量;
- 使用$GLOBALS;
- 使用global;
- 匿名函數使用use( );
三、遞歸
函數自己調用自己。
例:
<?php
function fun($num) {
echo $num,' ';
if ($num == 1) {
return;
}
fun($num-1);
}
fun(10);
?>
效果:
例從1加到100:
<?php
function fun($num) {
if ($num == 0) {
return;
}
return $num + fun($num-1);
}
echo fun(100);
?>
效果:
利用遞歸思想打印前10個斐波那契數:
<?php
function fun($num) {
if ($num == 1 || $num == 2) {
return 1;
}
else {
return fun($num-1) + fun($num-2);
}
}
for($i=1; $i<=10; $i++) {
echo fun($i),' ';
}
?>
效果:
四、包含文件
4.1 包含文件的方式
- require
- include
require和include的異同點:
require和include都可以包含多次,require一旦包含路徑輸錯,底下就不會執行了。include即使路徑發生錯誤,底下如果還有代碼還會執行。
例:
header.php代碼如下:
<h1>我是頭部</h1>
<?php
require './header.php';
require './header.php';
include './header.php';
include './header.php';
echo 'aa';
?>
效果:
然後我們故意輸錯require的路徑:
<?php
require './header1.php';
echo 'aa';
?>
效果:
報錯了,並且底下代碼不執行了,接着我們改成include:
<?php
include './header1.php';
echo 'aa';
?>
效果:
給了一個警告,並且aa也打印出來了。
4.2 包含文件的路徑
./ 當前目錄
../ 上一級目錄
如果不寫./
,那麼受include_path
影響,可以看下phpinfo
中的信息:
可以使用set_include_path()
去設置路徑。使用場景:如果包含文件的目錄結構比較多,可以用set_include_path()
去設置。set_include_path()
用分號分隔。
五、錯誤處理
5.1 錯誤的級別
- notice:提示
例:
<?php
echo $num;
?>
效果:
2. warning:警告
例:
<?php
include('./bb.html');
?>
效果:
3. fatal error:致命錯誤
例:
<?php
require('./bb.html');
?>
效果:
notice和warning報錯後會繼續執行下面代碼,error報錯後會停止執行。
5.2 錯誤的提示方法
- 顯示在瀏覽器上
- 記錄在日誌中
記錄在日誌中(在php.ini中配置也可以在函數中修改):
- error_reporting = E_ALL ( 報告所有的錯誤)
- display_errors = On (將錯誤顯示在瀏覽器上)
- log_errors = On(將錯誤記錄在日誌中)
- error_log=‘地址’(錯誤日誌保存的地址)
在項目開發過程中有兩個模式,開發模式,將錯誤顯示在瀏覽器中就可以了。生產模式的話需要將錯誤保存在日誌中,不能顯示在瀏覽器中。
例:
<?php
$debug = true; // 假設爲開發模式
ini_set('error_reporting',E_ALL); // 設置php配置 所有的錯誤有報告
if ($debug) { // 開發模式
ini_set('display_errors','On'); // 錯誤顯示在瀏覽器中
ini_set('log_errors', 'Off'); // 不記錄日誌
}
else { // 生產模式
ini_set('display_errors','Off'); // 錯誤不顯示在瀏覽器中
ini_set('log_errors', 'On'); // 記錄日誌
ini_set('error_log', './err.log'); // 記錄在當前目錄下
}
// 測試
echo $num;
?>
開發模式效果,顯示在瀏覽器中:
接下來我們修改爲生產模式:
<?php
$debug = false; // 假設爲開發模式
ini_set('error_reporting',E_ALL); // 設置php配置 所有的錯誤有報告
if ($debug) { // 開發模式
ini_set('display_errors','On'); // 錯誤顯示在瀏覽器中
ini_set('log_errors', 'Off'); // 不記錄日誌
}
else { // 生產模式
ini_set('display_errors','Off'); // 錯誤不顯示在瀏覽器中
ini_set('log_errors', 'On'); // 記錄日誌
ini_set('error_log', './err.log'); // 記錄在當前目錄下
}
// 測試
echo $num;
?>
開發模式下,瀏覽器效果看不到報錯:
那麼我們打開demo.php所在的目錄可以發現多了一個err.log,我們打開查看:
5.3 自定義錯誤處理方式
通過trigger_error
產生一個用戶級別的error/warning/notice
信息。
例:
<?php
$age=-10;
if ($age<0) {
trigger_error('年齡不能小於0');
}
?>
效果:
默認觸發了notice
級別的錯誤。
改爲warning級別的錯誤:
<?php
$age=-10;
if ($age<0) {
trigger_error('年齡不能小於0', E_USER_WARNING);
}
?>
效果:
類似的:E_USER_NOTICE,E_USER_WARNING,E_USER_ERROR
5.4 自定義錯誤處理函數
例:
<?php
function err() {
echo '我是自定義錯誤處理函數';
}
set_error_handler('err'); // 註冊錯誤處理函數
echo $num; // 只要有錯就會觸發這個函數
?>
效果:
自定義錯誤處理函數參數,規定四個參數,並且參數名規定了,$errno,$errstr,$errfile,$errline
。
例:
<?php
/**
* err 自定義錯誤處理函數
* @param $errno int 錯誤類型
* @param $errstr string 錯誤信息
* @param $errfile string 文件地址
* @param $errline int 錯誤行號
*/
function err($errno, $errstr, $errfile, $errline) {
switch($errno) {
case E_NOTICE:
case E_USER_NOTICE:
echo 'notice 錯誤<br/>';
break;
case E_WARNING:
case E_USER_WARNING:
echo 'warning 錯誤<br/>';
break;
case E_ERROR:
case E_USER_ERROR:
echo 'ERROR 錯誤<br/>';
break;
}
echo "錯誤信息:{$errstr}<br/>";
echo "錯誤文件:{$errfile}<br/>";
echo "錯誤行號:{$errline}<br/>";
}
set_error_handler('err'); // 註冊自定義錯誤處理函數
// 測試錯誤
echo $num;
?>
效果:
六、文件夾操作
6.1 創建文件夾(mkdir(路徑,權限,是否遞歸創建 ))
<?php
mkdir('./dir');
效果:
<?php
mkdir('./dir/aa');
在dir文件下創建aa文件夾。dir文件夾必須存在,如果不存在就報錯了。
那如果dir文件夾不存,我希望在./dir/aa
這樣寫的時候連dir文件夾也一起創建了,就需要用到第三個參數遞歸創建。
例:
<?php
mkdir('./dir/aa/cc', 0777, true); // 遞歸創建
效果:
6.2 刪除文件夾(rmdir())
例:
<?php
rmdir('./dir/aa/cc'); // 刪除cc文件夾
效果:
例:
<?php
rmdir('./dir');
效果:
刪除文件夾的必須爲空才能刪除,否則會報錯。
php沒有提供遞歸刪除。
6.3 重命名文件夾(rename(舊名字,新名字))
例:
<?php
rename('./dir', './dic');
效果:
6.4 是否是文件夾(is_dir())
例:
<?php
echo is_dir('./dic') ? '是文件夾' : '不是文件夾';
效果:
6.5 打開文件夾、讀取文件夾,關閉文件夾
- 打開文件夾:
opendir(),例:
<?php
var_dump(opendir('./'));
效果:
2. 讀取文件夾:
readdir(),例:
<?php
$folder = opendir('./');
while ($f = readdir($folder)) { // 利用while進行一直讀取,如果讀完了就爲空,循環就結束了。
echo $f,'<br/>';
}
效果:
首先出現一點和兩點,這是php的特性,只要有讀取文件夾就會出現這兩個。
tips:解決亂碼的問題,可以使用iconv(進去編碼格式,出來編碼格式,字符串)。
可以使用如下語法將 .
和 ..
去除掉:
<?php
$folder = opendir('./');
while ($f = readdir($folder)) { // 利用while進行一直讀取,如果讀完了就爲空,循環就結束了。
if ($f=='.' || $f=='..') {
continue;
}
echo $f,'<br/>';
}
效果:
3. 關閉文件夾:
closedir(),例:
<?php
$folder = opendir('./');
while ($f = readdir($folder)) { // 利用while進行一直讀取,如果讀完了就爲空,循環就結束了。
if ($f=='.' || $f=='..') {
continue;
}
echo $f,'<br/>';
}
closedir($folder);
在學習的php的路上,如果你覺得本文對你有所幫助的話,那就請關注點贊評論三連吧,謝謝,你的肯定是我寫博的另一個支持。