目錄
php最基本的文件上传
上传文件练习,最基本的形式
PHP处理HTTP请求和SESSION管理
cookie
概述
Cookie的获取:
分类
Session cookie (会话cookie)
Persistent cookie (持久cookie)
Secure cookie(安全cookie)
HttpOnly cookie
页面静态化
缓存
php与内存缓存redis
脑补
安装redis
redis基本命令使用
php配置redis
运行
先开redis-server
再开redis-client
执行php代码

php复习

Jun 23, 2016 pm 01:25 PM

最近要用php,好久不用感觉手生。抓起《零基础学PHP》一书复习了下,顺带学了smarty模板语言,然后到慕课网看了些php中级视频教程,这里记录下。

php最基本的文件上传

不用任何第三方库,纯html+php的文件上传。想想很简单,其实从文件传输出错的返回码也能看出程序写的怎么样,是否考虑到了所有情况。

从upload.html提交表单,上传文件到upload.php页面

upload.html:

<!DOCTYPE HTML><html><head>	<title>文件上传练习</title></head><body>	<h1 id="上传文件练习-最基本的形式">上传文件练习,最基本的形式</h1>	<form enctype="multipart/form-data" action="upload.php" method="post">		上传此文件:<input type="file" name="myfile" />		<input type="submit" value="提交上传" />	</form></body></html>
登入後複製

upload.php

<?php$upload_path = $_SERVER['DOCUMENT_ROOT']."/upload/";//basename():返回路径中的文件名部分$dest_file = $upload_path.basename($_FILES['myfile']['name']);if(move_uploaded_file($_FILES['myfile']['tmp_name'], $dest_file)){	echo "文件已经上传至服务器根目录的webbasic/upload目录下";}else{	echo "文件上传中发生了一个错误,错误代码:".$_FILES['myfile']['error']."<br/><br/>";	//var_dump($_FILES);	//测试发现:如果upload路径不存在,则上传肯定失败,但是$_FILES['myfile']['error']返回值为0,看不出错误。	//也就是说,分成“上传”和“移动”两部分,$_FILES['myfile']['error']只负责“上传”,而是否移动成功则需要根据move_uploaded_file()返回值来判断。	echo "错误分析:";	$err_num = $_FILES['myfile']['error'];	//参考:http://php.net/manual/zh/features.file-upload.errors.php	switch($err_num){		case 0:			$err_msg = "服务器上传文件存放目录出错";			break;		case 1:			$err_msg = "上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值";			break;		case 2:			$err_msg = "上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值";			break;		case 3:			$err_msg = "文件只有部分被上传";			break;		case 4:			$err_msg = "没有文件被上传";			break;		case 6:			$err_msg = "找不到临时文件夹";			break;		case 7:			$err_msg = "文件写入失败";			break;		default:			$err_msg = "其他错误!!";	}	echo $err_msg;}?>
登入後複製

PHP处理HTTP请求和SESSION管理

HTTP是无状态协议,服务器无法仅根据HTTP协议来判断发起请求的用户们谁是谁,要用SESSION来区分。实际上这里还需要客户端浏览器开启cookie来配合,cookie先不表。

最简单的场景:用户提交用户名和密码进行登录,发送的是POST请求,这个表单放到html页面就可以;表单提交后希望查看用户名和密码的具体值,要求刷新页面(再次发POST请求)、直接访问该页面(在浏览器地址栏后面敲回车,GET请求),都能正常显示用户名和密码的具体值。当然,如果是没有登陆过就来查看这个页面,也不应当显示用户名和密码,要重定向到登录页。

值得注意的一点:php中重定向比较常见,转发则比较麻烦。转发用header("Location:http://www.example.com/some.html")

登录页代码:

<!DOCTYPE html><html><head>	<meta charset="utf-8" />	<title>练习题3.4.1</title></head><body>	<form name="login" action="prac_bowl.php" method="post" onsubmit="return check_name()">	<table border="0" width="300px" align="center">		<tr>			<td>用户名:</td>			<td><input type="text" name="user_name"></td>		</tr>		<tr>			<td>密码:</td>			<td><input type="password" name="user_pass"></td>		</tr>		<tr>			<td><input type="submit" value="提交"></td>		</tr>	</table></form></body></html>
登入後複製

请求处理页:

<?phpsession_start();if(isset($_SESSION['user'])){	$user = $_SESSION['user'];	$pass = $_SESSION['pass'];}else{	//第一次发起POST请求,那么检查POST中相应字段是否不为空	if(isset($_POST['user_name']) && isset($_POST['user_pass'])){		//POST相应字段不为空,则取出值并赋值给SESSION存储		$user = $_POST['user_name'];		$pass = $_POST['user_pass'];		$_SESSION['user'] = $user;		$_SESSION['pass'] = $pass;		}else{		//POST相应字段有空值,或者不是POST请求,那么重定向到登录页面		header("Location:http://localhost/snowball/prac_login.html");		exit();	}}echo "用户名:".$user.'<br/>';echo "密码:".$pass.'<br/>';?>
登入後複製
学习Cookie

概述

HTTP是无状态协议。如果一个服务器不需要识别不同的用户,也就不需要维持不同用户的状态,就不用SESSION和COOKIE。

服务器为了识别当前请求发起者的身份,通过COOKIE和SESSION一起,进行识别,流程:
服务器会在客户端首次发起请求时,生成独一无二的SESSION_ID,并以Cookie的形式返还给用户,存储在用户浏览器中。
每次浏览器加载网站,浏览器都会把cookie发送给服务器,以通知服务器本用户先前的活动。

/*
Question:Cookie是通过HTTP协议发送的吗?SESSION是通过HTTP协议发送的吗?
是和表单请求和请求相应一起发送的吗?
Guess:应该是放在HTTP报文中的,和表单请求一起、和请求相应一起。
Answer:是一起的。

Cookie的获取:

通过浏览器上抓包发现,HTTP响应中的响应头包含Set-Cookie字段,值为“PHPSESSID=0e2vloo8fv35qpj448quostco1; path=/”形式

*/

分类

当用户浏览网站时被存储在临时内存中,关掉浏览器就会被删除的一种cookie

有确定的过期时间。生命周期内,每次用户访问相应网站时持久cookie的信息会被传送给服务器。
也称tracking cookie(跟踪cookie)

仅在使用加密连接(比如HTTPS)时被使用。

...

总结起来:
Session cookie(会话cookie)不带expire时间,那么相应地,HTTP响应中的Set-Cookie字段的值如果不带"Expires"或者"Max-Age"字样,那么一定是Session cookie。
/*
开个脑洞:wikipedia上说指定了Expires的cookie,会由浏览器在特定时间删除它。特定时间是什么?应该是Expires指定的deadline吧。那么我如果我的cookie还有24小时才过期,我现在关机,过了两天后我打开电脑但是不运行浏览器,或者干脆把硬盘拆下来接到另一个电脑上去读取原有的cookie,不行吗?

或许把这样的cookie传送给server已经不行了,但是拿到这原始的cookie后我们可以去修改cookie的过期时间,去hack。

所以我觉得wikipedia上的说法不正确。不能说浏览器删除cookie,而是cookie自动过期,浏览器检测到他们过期了,所以才删除他们。
额,好纠结,好像绕进去了,反正就是过期的cookie不能用,要用就需要hack。
*/

/
新问题:服务器端怎样设定发送给客户端的cookie类型?主要是session cookie和track cookie。
/

页面静态化

静态化就是把动态页面的内容,输出到缓冲区(而不是直接给用户),缓冲区内容再输出到文件(静态文件),然后用户访问静态文件。
我认为模板技术就是复杂版的静态化技术:简单的静态化就是把标准输出进行缓存,然后将缓存写入文件;模板技术在进行缓冲的同时还包括变量替换、编译等。两者本质是相同的。
模板文件一般是html代码为主,php脚本语句穿插其中。

静态化的步骤:

ob_start();   //开启缓冲区get_variables();  //获取变量,相关计算等。比如从数据库获取查询结果require_once('./templates/xxx.tpl');  //引入模板文件。其实是执行了模板文件,只不过输出被重定向到缓冲区了。file_put_contents($targetStaticFile, ob_get_clean());   //把缓冲区内容取出并清空,然后把取出的内容写入到目标静态文件。  以后访问目标静态文件$targetStaticFile就可以查看结果了
登入後複製

一个更加完整的例子:
用户访问index.php,如果缓存文件距离上次修改时间在300秒(5分钟)之内,那么读取原有的缓存文件index.shtml;否则,重新从数据库读取数据并写入静态缓存文件index.shtml,并且在页面上显示。
index.php内容如下:

<?php/*页面静态化步骤1.连接数据库,然后从数据库里面获取数据2.把获取到的数据填充到模板文件里面3.需要把动态的页面转化为静态页面,生成纯静态化文件*/$targetStaticFile = './index.shtml';//页面静态化的第一种方法:利用缓存时间判断//在静态文件上次修改的300秒之内,那么不更新,直接取静态文件if(is_file($targetStaticFile) && (time() - filemtime($targetStaticFile)) < 300) {	require_once($targetStaticFile);}else{	//获取数据库中的数据	require_once('./db.php');	$connect = mysql_connect("localhost","root","");	mysql_select_db("test", $connect);	$sql = "select * from news where `category_id`=1 and `status`='open' order by id desc limit 5";	$result = mysql_query($sql, $connect);	$news = array();	while($row = mysql_fetch_array($result)){		$news[] = $row;	}	ob_start(); //开启output buffering	require_once('./templates/singwa.tpl');	file_put_contents($targetStaticFile, ob_get_contents());	//引入模板文件	}
登入後複製

这里使用了ob_get_contents()函数,表示去出缓冲区的内容。ob_get_clean()函数则与之不同,是取出缓冲区内容后要清空缓冲区。这里index.php页面被调用,显然用户是要看到内容的,因此不能把缓冲区内容清空,因而要使用ob_get_contents()而不是ob_get_clean()函数。

缓存

现学现卖,看了imook网上的视频,自己敲了一下。
所谓缓存其实就是把从数据库中等地方取出的数据,存储到磁盘文件(哦,内存缓存?我还没有学到那里,先说磁盘的缓存好了)。

缓存操作包括:读取缓存,写入缓存,删除缓存。修改缓存就算了,直接删除后重新写入好了。
这里缓存文件内容使用了json格式进行存储,因而使用了json_encode和json_decode来进行编码解码。

编写了两个php文件:test.php用来调用缓存, response.php是缓存具体操作的实现

test.php:

<?phprequire_once('./response.php');$data = array(	'id'=>1,	'name'=>'singwa',	'type'=>array(4,5,6),	'test'=>array(1,45,67=>array(123, 'tsysa'),),);$file = new File();//缓存操作,请分别注释掉其他行来验证缓存操作是否OK$result = $file->cacheData('index_mk_cache', $data);  //写入缓存//$result = $file->cacheData('index_mk_cache', null);    //删除缓存//$result = $file->cacheData('index_mk_cache');      //查询缓存echo "<pre class="brush:php;toolbar:false">";if($result){	var_dump($result);	echo "success";}else{	echo "error";}echo "
登入後複製
";?>

缓存操作的具体实现:

<?php/*$arr = array(	'id'=>1,	'name'=>'Chris'	);$data = "输出json数据";$newData = iconv('UTF-8', 'GBK', $data);echo $newData;echo json_encode($newData);*///静态缓存class File{	private $_dir;	const EXT = ".txt";	public function __construct(){		$this->_dir = dirname(__FILE__).'/files/';	}	public function cacheData($key, $value='', $path=''){		$filename = $this->_dir.$path.$key.self::EXT;				if($value===''){			return $this->getCache($filename);//value为空,则获取缓存		}else if(is_null($value)){			return $this->removeCache($filename);		}else{			return $this->putCache($filename, $value);		}	}	private function getCache($filename){		//获取缓存		if(!is_file($filename)){			return FALSE;		}else{			//第二个参数为true,表示返回一个array,而不是object			return json_decode(file_get_contents($filename), true);		}	}	private function removeCache($filename){		//删除缓存(文件)		return unlink($filename);	}	private function putCache($filename, $value){		//写入缓存		$dir = dirname($filename);//dirname:返回路径中目录的部分		if(!is_dir($dir)){			mkdir($dir, 0777);		}		//写入缓存文件的内容,可以是json格式,也可以是序列化的格式		return file_put_contents($filename, json_encode($value));	}}?>
登入後複製

php与内存缓存redis

脑补

就像使用mysql一样,需要一个client和一个server。server不管它,client可以是terminal形式,也可以是web页面形式。
比如说terminal的形式好了。那么使用redis也一样,也需要一个terminal。我们可以用redis-cli命令进入redis,类似于mysql进入到mysql的交互界面一样。

redis默认使用6379端口

安装redis

看你用什么系统了,Fedora下安装:

yum install redissystemctl enable redissystemctl start redis
登入後複製

windows下安装:
到这里下载

redis基本命令使用

redis-cli 进入交互式命令行
set 变量名字 变量值 #设置缓存
get 变量名字 #获取缓存
setex 变量名字 失效时间 变量值 #设置缓存值和失效时间

del 变量名字 #删除缓存

如果缓存变量不存在,返回(nil)

php配置redis

要先安装phpredis扩展。php默认带了mysql的扩展所以感受不到,其实都是需要扩展的。
当前(2015年9月4日14:40:46)phpredis扩展在windows下只支持

从网上直接下载编译好的dll文件即可,一定要选择和php对应的版本。
php_redis-5.5-vc11-ts-x86-00233a.zip http://d-h.st/4A5
php_igbinary-5.5-vc11-ts-x86-c35d48.zip http://d-h.st/QGH

php_redis-5.5-vc11-nts-x86-00233a.zip http://d-h.st/uGS
php_igbinary-5.5-vc11-nts-x86-c35d48.zip http://d-h.st/bei

php_redis-5.5-vc11-ts-x64-00233a.zip http://d-h.st/1tO
php_igbinary-5.5-vc11-ts-x64-c35d48.zip http://d-h.st/rYb

php_redis-5.5-vc11-nts-x64-00233a.zip http://d-h.st/N0d
php_igbinary-5.5-vc11-nts-x64-c35d48.zip http://d-h.st/c1a

下载后将php_igbinary.dll和php_redis.dll放入php的ext目录下,

然后修改php.ini,加入这两个扩展,注意顺序不要反了。

extension=php_igbinary.dll

extension=php_redis.dll

重新启动Apache即可。

运行

先开redis-server

在fedora下就是:

sudo systemctl start redis
登入後複製

在windows下通过mintty进入到redis安装目录,执行:

redis-server.exe redis.conf
登入後複製

再开redis-client

我的意思是,以终端的形式开启redis,即执行:

redis-cli
登入後複製

严格讲,php.ini中加载了redis,那么只要php代码中定义了一个redis对象并进行了连接,那也是redis的客户端了。

执行php代码

在php代码中执行redis相关的操作。无非就是设置、读取、删除缓存,以及设置缓存失效时间。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? 說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型? Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP和Python:代碼示例和比較 PHP和Python:代碼示例和比較 Apr 15, 2025 am 12:07 AM

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

See all articles