最近要用php,好久不用感觉手生。抓起《零基础学php》一书复习了下,顺带学了smarty模板语言,然后到慕课网看了些php中级视频教程,这里记录下。
php最基本的文件上传 不用任何第三方库,纯html+php的文件上传。想想很简单,其实从文件传输出错的返回码也能看出程序写的怎么样,是否考虑到了所有情况。
从upload.html提交表单,上传文件到upload.php页面
upload.html:
文件上传练习 上传文件练习,最基本的形式 上传此文件:
upload.php
php处理http请求和session管理 http是无状态协议,服务器无法仅根据http协议来判断发起请求的用户们谁是谁,要用session来区分。实际上这里还需要客户端浏览器开启cookie来配合,cookie先不表。
最简单的场景:用户提交用户名和密码进行登录,发送的是post请求,这个表单放到html页面就可以;表单提交后希望查看用户名和密码的具体值,要求刷新页面(再次发post请求)、直接访问该页面(在浏览器地址栏后面敲回车,get请求),都能正常显示用户名和密码的具体值。当然,如果是没有登陆过就来查看这个页面,也不应当显示用户名和密码,要重定向到登录页。
值得注意的一点:php中重定向比较常见,转发则比较麻烦。转发用header(location:http://www.example.com/some.html)
登录页代码:
练习题3.4.1 用户名:
密码:
请求处理页:
cookie 学习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=/”形式
*/
分类 session cookie (会话cookie) 当用户浏览网站时被存储在临时内存中,关掉浏览器就会被删除的一种cookie
persistent cookie (持久cookie) 有确定的过期时间。生命周期内,每次用户访问相应网站时持久cookie的信息会被传送给服务器。
也称tracking cookie(跟踪cookie)
secure cookie(安全cookie) 仅在使用加密连接(比如https)时被使用。
httponly cookie ...
总结起来:
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内容如下:
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 ;if($result){ var_dump($result); echo success;}else{ echo error;}echo
;?> 缓存操作的具体实现:
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相关的操作。无非就是设置、读取、删除缓存,以及设置缓存失效时间。