PHPのレビュー

WBOY
リリース: 2016-06-23 13:25:38
オリジナル
1258 人が閲覧しました

最近phpを使っているのですが、久しぶりに使いました。私は「ゼロから学ぶ PHP」という本を読んで復習し、smarty テンプレート言語も学びました。その後、MOOC にアクセスして、ここに記録した中級の PHP ビデオ チュートリアルをいくつか見ました。

phpでの最も基本的なファイルアップロード

サードパーティのライブラリは必要なく、純粋なhtml+phpファイルのアップロードです。実際、考えてみれば非常に簡単です。ファイル転送エラーのリターン コードから、プログラムがどの程度適切に記述されているか、すべての状況が考慮されているかどうかがわかります。

upload.html からフォームを送信し、upload.php ページにファイルをアップロードします

upload.html:

<!DOCTYPE HTML><html><head>	<title>文件上传练习</title></head><body>	<h1>上传文件练习,最基本的形式</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 は表示されていません。

最も単純なシナリオ: ユーザーはログインするためにユーザー名とパスワードを送信し、特定の値を確認したい場合は、このフォームを HTML ページに配置できます。ユーザー名とパスワードについては、ページを更新する必要があります (POST リクエストを再度送信します))。ページに直接アクセスします (ブラウザのアドレス バーの後ろで Enter キーを押し、GET リクエスト)、ユーザー名とパスワードの特定の値パスワードは正常に表示できます。もちろん、ログインせずにこのページを表示した場合、ユーザー名とパスワードは表示されず、ログイン ページにリダイレクトされます。

注目すべき点が 1 つあります。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

学習 Cookie

概要

HTTP はステートレスプロトコル。サーバーがさまざまなユーザーを識別する必要がなく、さまざまなユーザーのステータスを維持する必要がない場合、SESSION と COOKIE は使用されません。

現在のリクエストの開始者の ID を識別するために、サーバーは COOKIE と SESSION を一緒に使用してプロセスを特定します。
サーバーは、クライアントが初めてリクエストを開始するときに一意の SESSION_ID を生成し、それをサーバーに返します。 Cookie の形式でユーザーを認識し、ユーザーのブラウザに保存されます。
ブラウザがウェブサイトをロードするたびに、ブラウザはサーバーに Cookie を送信して、ユーザーの以前のアクティビティをサーバーに通知します。

/*
質問: Cookie は HTTP プロトコル経由で送信されますか? SESSIONはHTTPプロトコル経由で送信されますか?
フォームリクエストとリクエストレスポンスと一緒に送信されますか?
推測: これは、フォームリクエストとリクエストレスポンスとともに HTTP メッセージに配置される必要があります。
答え: それは一緒です。

Cookie の取得:

ブラウザのパケット キャプチャにより、HTTP 応答の応答ヘッダーに Set-Cookie フィールドが含まれており、値 "PHPSESSID=0e2vloo8fv35qpj448quostco1; path=/" が

* の形式で含まれていることが判明しました。 /

カテゴリ

セッションCookie (セッションCookie)

ユーザーがWebサイトを閲覧するときに一時メモリに保存され、ブラウザを閉じると削除されるCookie

パーシステントCookie (永続Cookie)

一定の有効期限があります時間。ライフサイクル中、ユーザーが対応する Web サイトにアクセスするたびに、永続 Cookie の情報がサーバーに送信されます。
トラッキング Cookie (トラッキング Cookie) とも呼ばれます

セキュア Cookie (セキュリティ Cookie)

暗号化された接続 (HTTPS など) を使用する場合にのみ使用されます。

HttpOnly cookie

...

要約すると:
セッション Cookie (セッション Cookie) には有効期限がありません。したがって、HTTP 応答の Set-Cookie フィールドの値に「有効期限」が含まれていない場合、 " または "Max-Age" の場合、セッション Cookie である必要があります。
/*
心を開いてください: Wikipedia には、有効期限を指定した Cookie は特定の時間にブラウザによって削除されると記載されています。具体的な時間は何時ですか? Expires で指定された期限である必要があります。したがって、Cookie の有効期限までまだ 24 時間ある場合は、今すぐコンピュータをシャットダウンし、2 日後にコンピュータの電源を入れますが、ブラウザは実行しません。あるいは、単純にハード ドライブを取り外して別のコンピュータに接続して、オリジナルのクッキーは機能しませんか?

おそらく、そのような Cookie をサーバーに送信することはもう不可能ですが、元の Cookie を取得した後は、Cookie の有効期限を変更してハッキングすることができます。

つまり、wikipediaの記述は間違っていると思います。ブラウザが Cookie を削除するとは言えませんが、Cookie の有効期限は自動的に切れ、ブラウザは有効期限が切れたことを検出して削除します。
うーん、かなり混乱しているようですが、期限切れの Cookie を使用するにはハックが必要です。
*/

/
新しい質問: サーバーはクライアントに送信される Cookie のタイプをどのように設定しますか?主にセッション Cookie とトラック 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相关的操作。无非就是设置、读取、删除缓存,以及设置缓存失效时间。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート