非常抱歉,關於部落格內 PHP 的部分目前已經停止維護,因本人已經很久沒有寫 PHP ,且文章中所使用的 PHP 版本偏舊,希望有心學習 PHP 的朋友們,可以參考 Codecademy 的課程,或近一步嘗試 Laravel 這個 PHP 框架(可透過 laracasts 學習),若有找不到錯的學習資源也歡迎在留言串分享,方便有需要的人能夠有更多學習的管道!
第五堂課,我們要來練習製作一個計數器,可以記錄網站有多少人來瀏覽過。
可以玩玩看這次的成果喔:
fgets():取得資料
for(起始值;結束值;設定){回圈內容}:建立回圈
strlen():判斷字串長度(string length)
substr():取得部分字串(sub string)
for(起始值;結束值;設定){回圈內容}:建立回圈
strlen():判斷字串長度(string length)
substr():取得部分字串(sub string)
計數器製作
首先,我們打開DW後,開啟兩個新檔,一個是php檔,一個是文字檔,檔名分別取為p5.php和p5.txt。
接著,進入「設計」欄位,輸入「參觀人數:」
在p5.txt檔裡面,我們要設定的是計數器的起始值(這裡從1245開始),也就是即使沒有任何人來過,計數器會先從1245開始。
再來要來打php的語法了,這裡會用到open、gets和close,open和close已經在前一堂(第四堂)課有提過,fopen(檔案名稱,開啟模式),這裡我們開啟模式用r,表示唯讀。fgets則是新的語法,意思是取的資料。這裡在打的時候,要留意一下,用的是小括號,然後有些地方要記得加雙引號,每行結束要記得加上分號做結。
在內文的地方,我們則是希望echo出p5.txt裡面,我們剛剛輸入的數字。
預覽看看,卻發現有錯誤,到底錯誤發生在什麼地方呢?讓我們繼續看下去。
原來,之所以有錯誤,是因為我們這裡並沒有把抓起的資料建立成一個變數,$file只是把檔案開啟後的變數而已,並沒有把開啟的檔案讀出來。
因此,在這裡我們要把fgets的檔案建立一個新的變數,這裡我把它叫做num。同樣的,在內文的地方,我就要請它去幫我讀取num這個變數。
這時候預覽就會看到數字跑出來了喔!
可是,這不是計數器阿!這時候不管你怎麼按,數字都只會停留在1245而已。
為了要讓計數器會隨網頁被瀏覽的次數而改變,我們必須要增加以下的語法。
首先$num++,表示變數num會每一次都加一。fopen這裡,我們的開啟模式用的是w,意思是覆寫,也就是如果原本是1245,打開一次會加一,然後以1246覆寫進入原本的txt檔(這裡如果我們用的是a(寫入),會變成12451246)。fwrite則在上一堂課有學過,裡面放的是fwrite(檔案,寫入資料),所以這裡的意思是,我們把變數num,加一之後,再以覆寫的方式寫入p5.txt這個檔案中。
這時候,我們就完成第一部分了,數字會隨著點閱瀏覽器的次數而有改變了。
將計數器改為圖片呈現
再來這個部分就比較複雜一些,我們想要做的是,上面呈現的是「數字」,可是我們想要用圖片的方式來呈現,就像我們網頁最上方所呈現的樣子。
首先,我們到p5.php,一樣進入設計欄位,然後插入圖片(下載圖檔)。
取消掉就可以
接著程式碼的地方,就會產生一段「插入圖片」的程式碼
開始寫php嘍,這時候我們要把圖片呈現出來,一樣要用echo,echo後面用雙引號框住,然後把原本裡面的雙引號都刪除。
這時候會看到剛剛插入的圖片,可是只有一張,而且不會跟著參觀人數而改變。
所以我們現在的目標是要「根據參觀人數的位數,顯示不同張數的圖片」,也就是說如果瀏覽人數是2位數,就只要出現兩張圖片;如果瀏覽人數是4位數,就出現四張圖片。
為了解決這樣的問題,我們要用到「回圈」,想不到吧!
回圈的寫法上一堂課也有學過,for(起始值;結束值;設定){回圈內容}。
要怎麼用呢?我們的思考是這樣的,如果我們是一位數,則跑一次回圈(一張圖),兩位數,則跑兩次回圈(兩張圖)。
所以我們會碰到另一個問題─要怎麼判斷有幾位數呢?
遇到問題的時候,趕快讓我們來問問谷哥吧!
搜尋「php 判斷字串數」,發現我們可以用strlen這個函數,網站裡面有一些簡單的教學,可以參考看看要怎麼用。
這時候我知道用strlen就可以判斷我們的字串有幾位數,然後我把這個變數稱為string。
並且寫入回圈中,起始值是1,一直到<=我們的字串數,每次都加1。因此,如果我們的2位數,就會跑兩次回圈(1~2);如果我們是4位數,就會跑四次回圈(1~4)。
這時候預覽網頁,你就會發現,現在圖片的數目根據字串的位數成數。
這時候雖然圖片的數目會根據字串位數改變,可是圖片的數字不會變阿!該怎麼辦呢?
我們必須要找到方法,讓電腦能夠幫我們擷取某位數的數值。
這時候,我們又要請教谷哥大神了!
我們來試試看吧,我把擷取出來的數字取名叫做變數n,並且把圖片的連結也改成變數n。
這個意思是,從num從0(最左邊)開始,向右擷取一個數值。
預覽結果會發現,因為從最左邊向右擷取1個,所以慧黠取到「1」這個數值,而且4個都是1,並沒有根據我們的參觀人數而變,代表我們寫的還不夠完整。
這時候,我們可以修正一下寫法,擷取字串的地方,根據回圈i來擷取(這裡要思考一下),當i是1時,會從左邊數來第一個擷取右邊一個;當i是2時,會從左邊數來第二個擷取右邊一個。
預覽一下,看起來好像不錯,但是還是有個bug,因為他不是從最左邊那個(0)開始擷取,而是從左邊數來第一個(1),所以第一個抓到的值是2,最後一個值就抓讀到了(4右邊沒數字了)
因此,我們要修正一下,把i變成從0開始,為了不要讓圖片數目多1,因此把<=改成<,這樣跑得回圈數也會是一樣的。預覽看看!成功嘍!
加入session,避免瀏覽人數透過重新整理加以灌水
最後,我們會發現到,在這個網頁中,只要一直按重新整理,計數人數就會一直跑!這樣不就很容易可以灌水瀏覽人數了嗎?這到底該怎麼辦才好呢?
這時候,我們必須要用到SESSION這個指令,之後我們會在做更多關於SESSION的介紹,這裡先看看怎麼執行就好:
在語法的最上面要加上「session_start()」,表示開始session。
下面則是寫一段if語法,告訴電腦如果come不是v(第一次瀏覽的話come會沒東西,所以不會是v),則執行num++,也就是計數器加一,接著把它的come設成v,這樣在網友沒有關閉瀏覽器的情況下,他的come就會是v,下次進來的時候計數器就不會增加。
本次課程的完整語法如下:
<?php session_start(); $file=fopen("p5.txt","r"); $num=fgets($file); fclose($file); if($_SESSION['come']!='v'){ $num++; $file=fopen("p5.txt","w"); fwrite($file,$num); fclose($file); $_SESSION['come']='v'; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="https://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>製作計數器</title> </head> <body> 參觀人數: <?php echo "$num"; $string=strlen($num); for($i=0;$i<$string;$i++){ /* $n=substr($num,$i,1);*/ echo '<img src=counter/'.substr($num,$i,1).'.png width=48 height=48 />'; } ?> </body> </html>
補充
1.也可以用這種寫法,把函示塞到echo裡面,這裡要注意的是雙引號裡面可以接變數,但是不能接函式,所以我們必須要用單引號框住前後,同時把含式用「.」和前後的字串連接。
2.更多關於php字串的函式可以參考這裡。
來看看結果吧
以上內容均為本人在馬老師雲端研究室學習所整理之筆記
哈囉 想請問一下~ 若把 PHP 跟 HTML 跟開寫
回覆刪除PHP 要把 瀏覽人數的資料 傳到 HTML 的方法 怎麼實現呢!!?
PHP怎麼丟 HTML 怎麼接 ~
感恩感恩!
不好意思,不是很懂你的意思,你指的PHP丟?是指用MYSQL資料庫嗎?還是什麼呢?
刪除請問一夏 如果我要把觀看人數 寫入資料庫 然後讀取觀看次數的時候是讀取資料庫的次數 要怎麼改呢?
回覆刪除如果是寫到mySQL資料庫的話,那就會用到資料庫的語法去把資料寫入資料庫當中「mysql_query("insert into 資料表 (欄位名稱1,欄位名稱2,...) value(‘欄位1值’,’欄位2值’…..)")」,資料庫的寫入可以參考http://pjchender.blogspot.tw/2015/04/php-mysql-13.html 這篇的做法。
刪除v謝囉
刪除請問一夏 如果我要把觀看人數 寫入資料庫 然後讀取觀看次數的時候是讀取資料庫的次數 要怎麼改呢?
回覆刪除您好,我依照session_start();語法輸入
回覆刪除但是卻出現這樣的錯誤,想請問是為甚麼呢?
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:\AppServ\www\homework\p5-1.php:1) in C:\AppServ\www\homework\p5-1.php on line 2
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:\AppServ\www\homework\p5-1.php:1) in C:\AppServ\www\homework\p5-1.php on line 2
請問你在session_start()的上面有寫其他程式嗎?
刪除-----
刪除感謝您抽空回我,這段程式碼,我將它放在整個程式最上面,
沒使用session之前都是正確 但加入了session之後就出現問題了
session_start();
刪除$file=fopen("p5-1.txt","r");
$count_man = fgets($file);
fclose($file);
if($_SESSION['come']!='v'){
$count_man++;
$file=fopen("p5-1.txt","w");
fwrite($file,$count_man);
fclose($file);
$_SESSION['come']='v';
}
我找到問題了,是因為檔首BOM的關係,我搞定了^^
刪除