php针对文件、目录的相关知识

编    写:袁    亮
时    间:2015-07-07
说    明:php针对文件、目录的相关知识

一、linux文件权限
linux是一个多用户,多任务的系统,因此所有文件、目录、进程等等,都存在所谓的权限概念
1、3组用户:拥有者、所属组、其他用户(特殊账户:root)
2、基本权限:读权限、写权限、执行权限
3、简单例子,想了解更多请自行了解学习
ll yl.php #shell命令,列出这个文件的信息
-rwxrwxr-x  1 ci123dev apache  1278 6月   9 10:42 yl.php #输出结果
第一个字符:-:代表普通文件,l:代表软连接,d:代表是一个目录(其他b,c等自行了解)
第2-4:代表文件夹游泳者的读写执行权限,rwx代表三种权限都有,如果有-代表对应位置的权限没有
第5-7:代表所属用户组拥有的权限
第8-10:代表其他用户拥有的权限
ci123dev:代表这个文件属于ci123dev这个用户
apache:代表这个文件属于apache这个用户
1278:代表这个文件大小,字节
6月   9 10:42:后面是文件的最后修改时间(想看完整时间,可以加--full-time参数,或者stat查看文件)
4、更改权限或者用户组,具体用户,另查
chmod a+r yl.php
chown ci123dev:apache yl.php

5、注意:windows下的编码是gb2312的,针对文件名、路径等,需要注意编码转化

二、常用文件操作函数
1、一次性读取文件:file_get_contents
1.1 读取文件的首选方法,最简单
1.2 如果文件太大,不能使用该函数,很容易会卡死
1.3 也可以用于读取远程链接的内容,url如果有特殊字符,需要使用urlencode编码
1.4 可以从指定位置,读取限制最大长度的内容
1.5 高阶:
配合strem来修改http头信息,这种情况,直接使用curl会更方便些
// Create a stream
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
)
);
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);
2、一次性写入文件:file_put_contents
2.1 如果文件不存在,则尝试创建,注意:文件夹不会主动创建,所以必须保证文件存在
2.2 如果文件存在,则覆盖写入,除非设置了追加模式,第三个参数
3.3 写入模式:
FILE_USE_INCLUDE_PATH:在include的目录里搜索,这个一般用不到,除非php配置中设置了include_path
FILE_APPEND:内容追加到文件尾部,不覆盖,日志记录的时候一般都用这个
LOCK_EX:写入的时候,锁定文件,不允许其他人写
3.4 写入内容的格式:string或者一维数组,多维数组或者对象等会写入失败
多维数组可以采用,var_export($data,1);或者json_encode($data);转为字符串写入,推荐var_export
3、将上传上来的文件移动到指定目录
move_uploaded_file与copy,rename不一样,它会检查被移动的文件是否是上传的文件
安全性较高,在做文件上传的时候,只运行以这个来移动
4、针对同一个文件,多次操作;注意:打开的所有句柄,必须关闭
4.1 打开文件句柄,作为后面的操作资源
fopen
模式设置:以什么模式打开,具体参考手册,很重要
4.2 文件读
fread:读取指定长度内容
fgetc:读取一个字符
fgets:读取一行,默认一行最大1K,超出则不读取,可以自己设置
feof:判断是否到了文件结尾
4.3 文件写
fwrite:将内容写入文件中,可以设置最大写入长度
4.4 关闭文件句柄
fclose:关闭句柄
5、文件判断
file_exists:文件或目录是否存在
is_file:判断是否是一个正常文件
6、其他
dirname:去掉最后一层目录或者文件名
ps:配合__FILE__来计算绝对路径,可以查看项目中global.php的写法

三、其他文件函数,了解为主
1、文件判断
is_readable :是否可读
is_writable :是否可写
is_uploaded_file :是否上传上来的文件
2、文件本身操作
filesize:文件大小
rename:剪切文件
copy:复制文件
unlink:删除文件
3、ini文件读取
parse_ini_file
parse_ini_string
4、其他
basename:去除路径,只获取文件名
flock:给文件加锁

四、目录常用函数
1、判断是否文件夹:is_dir
2、创建文件夹:mkdir
3、删除文件夹:rmdir
4、读取文件夹下文件:
4.1 glob:显示符合规则的文件夹下有哪些文件,推荐使用
4.2 readdir 读取由opendir打开的目录
4.3 dir函数配合read使用

清除session时的一个小bug

编    写:袁    亮
时    间:2014-09-23
说    明:清除session时的一个小bug

1、清除所有session,不能使用unset($_SESSION);
单个session可以通过unset来删除,比如unset($_SESSION['GOODS']);
session的过程是在php执行session_start的时候,先查看cookie中是否有相应的sessionid
如果有,则将对应session名中的值,取出来,反序列化,变成一个php全局变量$_SESSION
执行过程中,session变量可以随意改变
脚本结束后,将session变量序列化,然后回写到对应sessionid中(这个时候,如果没有相应全局变量应该不会回写,从而导致该问题)

2、session常见优化:
开启session之后,访问量稍微大点,web服务器的IO压力就会急剧上升,因为默认是通过文件形式来做session的读写
一个简单的优化办法就是将session的存储方式改成Memcache形式,将php.ini中所有的session设置去除,加一下三行即可
[Session]
session.save_handler = memcache
session.save_path=tcp://192.168.0.106:11216

session相关知识总结文档

编    写:袁    亮
时    间:2015-01-15
说    明:session相关知识总结文档

一、说明
1、session是存储当前用户的一些信息
2、数据存储在服务器的文件中
3、session管理一个客户端(用户),一般通过cookie的形式
4、session可以让一个用户的数据在不同的页面之间互通

二、生存周期
1、服务端通过session_start开启session功能
前面不能有输出(因为这一步需要设置一个http头,设置cookie用)
2、初始化数据信息
判断之前有没有session的对应cookie(默认叫PHPSESSID)
如果有,则找到对应的文件,将文件内容读取,反序列化成php数组$_SESSION
如果没有,则$_SESSION为空
3、在脚本中,添加、删除、更改session数组的内容,即时生效
4、脚本运行结束,php进程将$_SESSION数组的内容,序列化,并重新写入到服务器对应文件中
如果整个$_SESSION被unset注销掉,会导致php进程跳过该操作,从而使得修改过的session没有保存,从而出错
5、session过期
PHPSESSID是一个会话形式的cookie,在浏览器关闭的时候就失效,从而使得session文件不再由对应的客户端用户
服务端会定时对session文件进行销毁,一般是24分钟(默认值1440秒)
session销毁是以概率形式的,这个概率在php配置中设置

三、SESSION存储方式
1、默认是使用cookie来和客户端进行对应关系,但也设置通过get形式来传递(不建议)
2、从上述周期看,每一次使用session都会涉及到文件的读写,在QPS较高的情况下,IO影响很大
可以在php中配置,使用memcache作为session存储的载体,从而把io降下来
[Session]
session.save_handler = memcache
session.save_path=tcp://192.168.0.106:11216
也可以自己写程序将session的所有操作重写,不建议这么干
3、cookie只能存储字符串,session可以存储object,数组等更复杂的数据
4、cookie的长度受限制,各浏览器不一样,session基本没有,但不建议存储太大的数据进去

四、php操作session
1、开启session
session_start();
如果前面有输出,会报错,可以通过ob系列函数解决该问题
2、session增、改,正常全局变量使用
$_SESSION['test'] = 'add';
$_SESSION['test'] = 'edit';
3、session删除
unset($_SESSION['test']);
session_destroy();清除所有session
不要unset($_SESSION);

cookie相关知识点总结

编    写:袁    亮
时    间:2015-01-15
说    明:cookie相关知识点总结

一、说明
1、http协议是无状态的,每一次请求之间互相独立,为了区分不同的客户端、用户,采用cookie进行标识
2、cookie内容保存在本地txt文件中,类似如下(火狐的):
.ci123.com    TRUE    /flashsale/sadmin    FALSE    1451097200    vip_plat    test3
作用域名        httponly 作用路径            https    过期时间     cookie名     cookie值

二、生存周期
1、服务端设置一个cookie,在http响应头里,会有一个头信息叫set-cookie的
在header头输出之前,不能有任何输出,因此setcookie之前也不能有任何输出
2、浏览器收到该头信息,会写入到客户端的cookie文件中
3、下次发起请求时,会将符合条件的cookie,从本地文件夹中将cookie字符串读取,拼接到http请求头里
只会发送未到过期时间的cookie
该时间以客户端机器为准(因此有时候会出现cookie设置不起来,因为用户电脑的时间不对,导致设置的cookie一直都是已经过期了的)
4、服务器接到http头信息里的cookie数据,将其格式化成相应的cookie数组
同名的cookie只有第一个有效,后面无用(顺序由浏览器根据相应策略决定)

结论:当前页面设置了cookie,本页面是取不到该cookie的,明白了上述流程自然清楚

三、php使用
1、设置cookie:
setcookie(name,value,expire,path,domain,secure,httponly);
2、删除cookie:(跟设置的时候保持一直,只将值设为空即可)
setcookie(name,'',expire,path,domain,secure,httponly);
3、获取cookie:
$val = $_GET['name'];

name:cookie的名称
value:cookie的值(没有值的时候,则注销该cookie)
expire:过期时间,unix时间戳(默认是0,会话,浏览器关闭则失效)
path:在域名的哪个目录下起效
默认只在设置的那个网址目录以及其子目录下有效
比如local.ci123.com/bbs/sub/post_add_sub.php中设置的一个cookie,默认只在/bbs/sub/以及其子目录下有效
domain:在哪个域下有效(只有域名的右前缀值有效,不是随便设置的
test.shop.ci123.com只能设置test.shop.ci123.com,shop.ci123.com,.ci123.com这三个值,默认是test.shop.ci123.com
secure:是否只能通过https发送(很少用,一般都是false)
httponly:js是否可以读取该cookie,一般不允许(设为true)

四、同名cookie
1、cookie名称并不能唯一的标识一个cookie,由三个东西唯一确定:cookie名+作用域(domain)+作用路径(path)
2、cookie名相同的情况下,浏览器会根据一定策略,重新排列cookie字符串,并发送给服务器,服务器只认第一个
1、作用路径顺序(在域名判断之前)
shop.ci123.com/flashsale/访问的时候有两个同名cookie,分别在以下作用路径,则/flashsale/有效
/flashsale
/
2、域名顺序
shop.ci123.com访问的时候有两个同名cookie,分别在以下作用域名,则shop.ci123.com有效
shop.ci123.com
ci123.com

五、工具
firefox的新版firebug插件就集成了cookie插件
chrome也有直接查看cookie的(网址左边的图标)

六、session与cookie的关系
session存储在服务端
一般是通过cookie来标识(不改默认配置的话,是叫PHPSESSID)

Mysql默认值

编    写:袁    亮
时    间:2014-11-17
说    明:Mysql默认值

1、默认值default设置
1.1 有设置:默认值
1.2 未设置:无

2、是否允许NULL值设置:
2.1 允许有(NULL)
default有值则为设置的默认值
default无值,则为NULL
2.2 不允许(NOT NULL)
default有值,而且不为NULL,则默认值为设置的值
default无值,则为对应字段类型的默认值(字符串的空字符串,整型的0)

3、自增长设置:AUTO_INCREMENT
3.1 不受default和是否允许NULL影响

4、时间戳:timestamp
4.1 默认为当前时间

内存不足导致sql执行过慢

编    写:袁    亮
时    间:2014-05-08
说    明:内存不足导致sql执行过慢

一、问题描述
1、某条sql执行了37秒
2、看慢日志里,被锁的时间在万分之几秒,因此不是因为被锁从而导致执行慢

二、问题分析
1、经与其他人沟通,可能是因为内存不足,导致索引没有加载到内存里,所以比较慢
mysql的所有会部分加载到内存里,如果内存不足的时候,会根据一定的策略将部分数据去除,重新读入数据到内存中
该内存大小设置可通过:show variables like '%key%';
然后设置set global key_buffer_size=2048000000;(2G)将该值改大
2、另外一种可能是在那个时间点,磁盘io有问题,从而导致读取数据变慢
但是如果是磁盘io卡住的话,那么那个时间点的其他sql应该也会卡,而看慢日志里,附近时间点并没有其他的慢查询
查看那个时间点的io,正常

三、总结
1、mysql启动或者重启的时候,因为要把索引加载到内存中,刚重启的时候,可能会导致服务器的io等负载过高,重启就挂
2、mysql一般来说,不能直接关,关掉之后,会需要修复表
3、有些时候,会执行的很慢,很有可能就是内存给的不够,一般4个G,机器较好的话,可以给4G

关于mysql截断内容问题

袁亮,2014-03-14,关于mysql截断内容问题解决

 

  • 问题描述:
  • 当用户发表有某些特殊字符的内容时,存入mysql数据库的内容会被截断

2、数据库、程序文件等都是utf-8编码

3、确认sql正常

 

  • 原因:
  • mysql中utf8编码最多只能是3个字节(5.3版本后,有utf8mb4类型可支持4个字节的utf8)
  • utf8是一种1-4个字节的可变字符编码(英文1个字符,汉字3个字符)
  • 某些特殊字符(emoji表情符号等)是4字节的utf8编码
  • Mysql在遇到超过最大字节范围的字符时,会忽略其后面的字符串,从而导致内容丢失

 

  • 解决思路:
  • 升级mysql到5.3版本以上,并将字段的编码设置为utf8mb4类型
  • 通过程序,将字符串中4字节的utf8字符替换或者删除即可

 

  • 剔除utf8字符串中4字节的字符方法:

[code]

function removeByte4($str){

return preg_replace('/[\xF0-\xF7].../s','', $str);

}

[/code]

性能:台式机,4.6W字符,0.006s,对程序性能影响基本可以忽略

 

附:(其他的一些相关知识)

 

  • Utf8 4字节各系统的支持情况:

1、windows xp: xp系统不支持4字节utf8字符, 浏览器用占位符显示

2、windows 7: 支持4字节utf8字符

3、mac os x: 支持4字节utf8字符

4、iPhone/iPad: 支持4字节utf8字符

 

1、将特殊的4字节字符用相应的图片表情代替

2、替换的时候,注意不要堵塞用户的处理流程,当文本内容较长时,这是一个很耗性能的处理,建议先忽略4字节字符,然后将内容存到文件或者其他地方,后续使用脚本对这些内容进行替换处理等操作。

3、新浪微博等有做相应处理

4、特殊符合以及对应表情可参考网站:http://www.charbase.com/

  • 四种不同剔除utf8字符串中4字节字符的性能比对:

测试机:普通pc 测试文本:4.6W字节的中英文、特殊字符等混合

  • 极快,推荐使用:006s

function removeByte4($str){

return preg_replace('/[\xF0-\xF7].../s','', $str);

}

 

  • 较慢,参考用:2s

function removeByte4_2($str){

return preg_replace('/[\x{10000}-\x{10FFFF}]/u','', $str);

}

  • 慢,但方便对特殊字符做不同替换:3s

function removeByte4_1($str){//移除utf-8编码中4字节及以上的字符

mb_internal_encoding("UTF-8");

$len = mb_strlen($str);

$res = '';

for($i=0;$i<$len;$i++){

$t = mb_substr($str,$i,1);

$res .= strlen($t)<=3?$t:'';

}

return $res;

}

  • 极慢,不具使用价值,仅参考:9s

function remove_4_byte($string) {

$char_array = preg_split('/(?<!^)(?!$)/u', $string );

$len = count($char_array);

for($x=0;$x<$len;$x++) {

if(strlen($char_array[$x])>3) {

$char_array[$x] = "";

}

}

return implode($char_array, "");

}

svn常用命令

ps:从贾荣同学那拿过来的,大家可以参考下

1.svn checkout path(path是服务器上的目录)

例如:svn checkout svn://192.168.1.1/pro/domain

简写:svn co

2、Linux命令行下往版本库中添加新的文件

svn add file

例如:svn add test.php(添加test.php)

svn add *.php(添加当前目录下所有的php文件)

3、Linux命令行下将改动的文件提交到版本库

svn commit -m “LogMessage“ [-N] [--no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关)

例如:svn commit -m “add test file for my test“ test.php

简写:svn ci

4、Linux命令行下的加锁/解锁

svn lock -m “LockMessage“ [--force] PATH

例如:svn lock -m “lock test file“ test.php

svn unlock PATH

5、Linux命令行下更新到某个版本

svn update -r m path

例如:

svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本。

svn update -r 200 test.php(将版本库中的文件test.php还原到版本200)

svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,是因为冲突,需要先update,修改文件,然后清除svn resolved,最后再提交commit)

简写:svn up

6、Linux命令行下查看文件或者目录状态

1)svn status path(目录下的文件和子目录的状态,正常状态不显示)

【?:不在svn的控制中;M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】

2)svn status -v path(显示文件和子目录状态)

第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人。

注:svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是svn在本地的.svn中保留了本地版本的原始拷贝。

简写:svn st

7、Linux命令行下删除文件

svn delete path -m “delete test fle“

例如:svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file”

或者直接svn delete test.php 然后再svn ci -m ‘delete test file‘,推荐使用这种

简写:svn (del, remove, rm)

8、Linux命令行下查看日志

svn log path

例如:svn log test.php 显示这个文件的所有修改记录,及其版本号的变化

9、Linux命令行下查看文件详细信息

svn info path

例如:svn info test.php

10、Linux命令行下比较差异

svn diff path(将修改的文件与基础版本比较)

例如:svn diff test.php

svn diff -r m:n path(对版本m和版本n比较差异)

例如:svn diff -r 200:201 test.php

简写:svn di

11、Linux命令行下将两个版本之间的差异合并到当前文件

svn merge -r m:n path

例如:svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)

12、Linux命令行下SVN 帮助

svn help

svn help ci

以上是常用命令,下面写几个不经常用的

13、Linux命令行下版本库下的文件和目录列表

svn list path

显示path目录下的所有属于版本库的文件和目录

简写:svn ls

14、Linux命令行下创建纳入版本控制下的新目录

svn mkdir: 创建纳入版本控制下的新目录。

用法: 1、mkdir PATH…

2、mkdir URL…

创建版本控制的目录。

1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增调度,以待下一次的提交。

2、每个以URL指定的目录,都会透过立即提交于仓库中创建.在这两个情况下,所有的中间目录都必须事先存在。

15、Linux命令行下恢复本地修改

svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert:

用法: revert PATH…

注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复被删除的目录

16、Linux命令行下代码库URL变更

svn switch (sw): 更新工作副本至不同的URL。

用法: 1、switch URL [PATH]

2、switch –relocate FROM TO [PATH...]

1、更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的方法。

2、改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动(比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用这个命令更新工作副本与仓库的对应关系。

17、Linux命令行下解决冲突

svn resolved: 移除工作副本的目录或文件的“冲突”状态。

用法: resolved PATH…

注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的相关文件,然后让 PATH 可以再次提交。

18、Linux命令行下输出指定文件或URL的内容。

svn cat 目标[@版本]…如果指定了版本,将从指定的版本开始查找。

svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)返回比特网首页>>

svn的服务端搭建及使用

编    写:袁    亮
时    间:2015-01-27
说    明:svn的服务端搭建及使用

一、服务端搭建
1、svn 安装
yum install -y subversion
2、创建svn版本库
mkdir /opt/ci123/svnroot/
3、创建一个svn项目
svnadmin create /opt/ci123/svnroot/test
4、修改svn配置信息
4.1 添加账号:
vim /opt/ci123/svnroot/test/conf/passwd
root=249
4.2 账号权限
vim /opt/ci123/svnroot/test/conf/authz
[/]
root=rw
4.3 svn服务配置
vim /opt/ci123/svnroot/test/conf/svnserve.conf
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
5、启动svn服务
svnserve -d -r /opt/ci123/svnroot/ --log-file /tmp/svn_run.log
注意启动的目录是/opt/ci123/svnroot/
日志写入到/tmp/svn_run.log,方便后期定位问题
6、客户端使用
svn co svn://192.168.0.249:3690/test
#端口号3690可以不写,默认就是这个
7、再建另外一个svn
7.1 使用:svn://192.168.0.249:3690/ciphoto
7.2 创建服务端:
svnadmin create /opt/ci123/svnroot/ciphoto
同上,修改配置信息即可
8、删除一个svn目录
rm -rf /opt/ci123/svnroot/test
慎用,不可恢复

二、shell统一管理
1、配置文件统一
cp -r /opt/ci123/svnroot/ciphoto/conf /opt/ci123/svnroot/conf2
将其中的svnserve.conf引用的passwd和auth文件引用备份出来的配置文件
2、编写创建svn的shell脚本create.sh
#!/bin/sh
#袁亮,2015-01-27
#svn创建脚本

if [ ! "$1" ] ;then #项目名不能为空
echo '请输入你需要创建的svn名'
exit
fi

if [ -d "/opt/ci123/svnroot/$1" ];then
echo '该svn已经存在,请重新输入名称'
exit
fi

echo $1"的svn正在创建中"
res=`svnadmin create /opt/ci123/svnroot/$1`
cp /opt/ci123/svnroot/conf/svnserve.conf /opt/ci123/svnroot/$1/conf/svnserve.conf
echo $1"的svn创建完成,可以通过svn://192.168.0.249/$1 checkout下来访问"
3、执行方法
sh /opt/ci123/svnroot/create.sh test

三、后台管理形式
1、有开源的项目可以直接管理(不好用)
2、也可以自己定制开发,开发也简单

四、配置文件
1、auth文件中组设定
[groups]
geek=yuanliang,root
2、auth文件中给组权限
[/]
@geek=rw
3、所有账号都有读权限
[/]
*=r

附:
1、参考文档:
http://www.cnblogs.com/Anders888/p/4167389.html
http://www.2cto.com/os/201403/282669.html