编 写:袁 亮 时 间:2015-07-13 说 明:生成缩略图的两种策略 一、为什么需要压缩图片? 1、在各种web应用中,上传头像是一个非常常见的功能,比如头像、比如相册等等 2、用户上传的图片一般都很大,现在的手机拍的图片,基本上都是2-3M,如果是相机,6-7M,10来M也很正常 3、10M的图片,按现在用户的平均网速8M来说,那就是10MB/8Mb/s=10*8Mb/(8Mb/s)=10秒,浏览器显示一张照片就需要10秒,完全不能接受 4、一个网页或者界面,一般都会显示很多张图片,而且每张图片其实只显示了一个很小的尺寸 5、带宽费用很贵,因此图片显示,99%的地方都是显示的缩略图 二、两种压缩图片策略(图片不变形,变形的压缩不考虑,线上不允许使用) 1、将原图压缩生成一个指定宽高的图片 1.1 常见于头像等地方 1.2 生成的图片宽高固定,图片可能被裁减,很多时候需要使用js插件,让用户拖拽,确定裁减到什么位置 2、将原图压缩,宽高分别不能搞过某个值 2.1 相册等大多数情况 2.2 图片不会被裁减,但是生成出来的图片宽高不确定 三、php具体实现裁减 //引用php函数 include_once("image_function.php"); $old_src = '6.jpg'; $new_src = 'tmp/2013/02/27/2.jpg'; $new_width = 400; $new_height = 300; mkdir('tmp/2013/02/27',777,1); 1、方案1 $res = cutPhotoDesign($old_src,$new_src,$new_width,$new_height,$rate=100); 2、方案2 $res = cutPhoto($old_src,$new_src,$new_width,$new_height,$rate=100); 四、nginx裁图模块 1、使用程序来裁图,会遇到几个问题: 1.1 如果再增加一个缩略图尺寸,则需要对原来的所有图片重新处理一次,很麻烦 1.2 压缩图片,会使用户上传处理速度变慢 1.3 需要存储非常多份的缩略图 2、nginx有个扩展,阿里开源的,可以实现上面程序中的两种切图效果 2.1 找运维同事帮忙部署 2.2 nginx切图,访问缩略图的时候,nginx会看,是否已经有裁减过该尺寸的图片,如果有,直接访问,没有则裁减并缓存 2.3 配置的时候,缩略图规则写到最后 比如原图访问 http://***/***/a.jpg 则缩略图规则为 http://***/***/a.jpg_600x400
分类: 一年水平
curl阶段三:模拟用户表单提交数据
编 写:袁 亮 时 间:2015-07-10 说 明:curl高阶应用,模拟用户表单提交数据 一、应用场景 1、伪装用户登录,爬取需要登录才能访问的数据 2、提交表单,进行一些操作,比如自动发帖等,刷刷投票什么的 3、内部接口调用,模拟提交数据,作为参数 二、get传送 没什么好说的,直接在链接后面拼起来就好了 三、post数据传送 1、form表单提交数据,编码设置,直接参考w3cschool application/x-www-form-urlencoded 在发送前编码所有字符(默认) multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 text/plain 空格转换为 "+" 加号,但不对特殊字符编码。 2、一般的表单项 2.1 采用的是第一编码方式 2.2 代码使用: $data = array( 'title' => '大家好,我是新人,请多多关照', 'content' => '第一次来这边,发现好多东西好有帮助...', ); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//Post提交的数据包 3、文件上传 3.1 代码和上面一样 3.2 文件地址使用@符合加载绝对路径之前即可,先绝对路径,否则很容易出错 3.3 例如: $data = array( 'title' => '大家好,我是新人,请多多关照', 'content' => '第一次来这边,发现好多东西好有帮助...', 'photo' => '@/opt/ci123/www/html/ciphot/demo.jpg', ); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//Post提交的数据包 3.4 还有个参数 CURLOPT_UPLOAD,没用过,有兴趣可以自己了解下 四、http basic验证 1、有些项目或者网站,访问的时候加了http basic验证,直接抓取会失败 2、知道账号密码的话,简单设置下即可 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, "username:password"); 五、错误信息显示 1、在exec执行之后,如果出错,可以返回报错信息方便查看 $img = curl_exec($ch); $err = curl_error($ch); if($err){ return $err; } 2、很少用,一般是在上传图片的时候,图片路径出错会出这个问题 3、curl抓取不到,请注意是否能ping的通域名,能否正常访问那个文件,ping一下,或者wget下那个地址 4、ipv6报错提示:curl: (6) Couldn't resolve host(域名能正常访问的话),设置使用ipv4的 curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4)
curl阶段二:伪造请求信息及其他小知识
编 写:袁 亮 时 间:2015-07-09 说 明:curl请求伪造信息及其他小知识点 一、为什么需要伪造? 在抓取的过程中,经常会出现被人屏蔽,不给抓了,这个时候,我们需要让自己尽量像是一个正常的用户去抓取相应数据 二、伪造哪些信息? 1、useragent 1.1 最初级的,所有浏览器、app都会带上自己的ua信息,如果没有,那就是直接告诉别人,我不是一个正常访问 1.2 curl_setopt($ci, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0'); 1.3 ua内容,可以使用firebug,查看网络中的请求头信息,复制下来即可,也可以准备多个,随机使用 2、referer 2.1 浏览器告知服务端,上一个请求的链接是什么;特别是在图片的抓取上,很多网站都会判断referer是不是自己的网站 2.2 根据网址,自动伪造首页referer $urlinfo = parse_url($url); $host = $urlinfo["scheme"].'://'.$urlinfo['host']; curl_setopt ($ch, CURLOPT_REFERER, $host); 3、cookie 3.1 很多网站需要登录才能显示内容,这个时候,就需要伪造相应的登陆cookie,否则抓取不到内容 3.2 主要两种办法:一个是在浏览器里登陆相应的账号,从firebug等,查看请求头里的cookie内容,复制下来 第二种是使用账号密码,在curl中,模拟登陆,然后将cookie存到txt文件里,下次将cookie带上去抓取数据 3.3 第一种比较快捷方便,特别是有验证码的网站,适合短时间抓取,但可能会因为cookie失效等原因出问题 第二种,如果有验证码会很麻烦,但是优点在于只要账号密码不出问题,程序就很少出问题 3.4 第一种代码: curl_setopt ($ch, CURLOPT_COOKIE, 'BAIDUID=7268C693B1F385AC297F677E90E092D4:FG=1;BIDUPSID=6093A44AECD856D0FFBD012FA16D99BA; PSTM=1436169100; BD_UPN=13314352;BDUSS=VRFdUMyRndUWmdkLUxrTW5-d0NjSVZocktDVHdublh1SFhqRTFHSlB3c2piTVJWQVFBQUFBJCQAAAAAAAAAAAEAAAD6lOAweXVhbmxpYW5nODQ3XzEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPfnFUj35xVd;BD_HOME=1;H_PS_PSSID=11194_1442_14601_16148_13245_16035_10813_14429_10211_12868_16167_14667_16210_14954_15397_11465_13932_13612;BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0;BD_CK_SAM=1;__bsi=15490895447769138228_00_3_R_N_25_0303_C02F_N_I_I_0'); 3.5 第二种 伪造登陆的请参考阶段三,form表单伪造,cookie保存和下次使用就下面两段代码,注意文件写权限问题 curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_file); //连接结束后保存cookie信息的文件。 curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file); 4、使用代理访问 4.1 很多网站,都会对同一个ip的访问次数和频率做限制,这个时候可以使用代理来隐藏我们的ip 4.2 代理有很多种,具体的参考其他文档,网上找的免费代理经常失效,不稳定,所以保持代理库的及时更新非常重要 4.3 使用方法 curl_setopt($curl, CURLOPT_PROXY, '代理ip:代理端口'); 5、伪造ip 5.1 将自己作为代理的一层,伪造header中的x-forwared-for来达到 5.2 关于ip的相关知识,可以搜索查看其他文档 5.3 采用的伪造头信息来达到目标,上面的那些伪造也可以使用这个方法达成,只要对http头熟悉即可 $header = array( 'X-FORWARDED-FOR:202.103.229.40', '...'//其他需要伪造的,再加一行即可 ); curl_setopt ($ch, CURLOPT_HTTPHEADER , $header ); //构造IP 三、curl超时 1、所有curl请求,必须设置超时时间,否则很容易导致进场堆积,将服务器拖垮 2、超时有两个,一个是连接超时,一个是传输内容超时,都必须要设置 3、设置代码: curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT , 2 );//连接时间 curl_setopt ($ch, CURLOPT_TIMEOUT , 3 );//最长执行时间 四、跟踪链接跳转 1、抓取的时候,会出现目标被header跳转 2、跳转的代码在header中获取 curl_setopt($ch,CURLOPT_HEADER,true);//将头信息输出,默认只输出http的body部分(非html的body) curl_setopt($ch,CURLOPT_NOBODY,true);//不输出body数据,如果确定有location跳转的话用,一般情况下不要设置 3、设置代码: curl_setopt ($ch, CURLOPT_FOLLOWLOCATION , true );//跟随跳转 curl_setopt ($ch, CURLOPT_MAXREDIRS , 2 );//跳转次数限制,防止死循环等
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使用
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,对程序性能影响基本可以忽略
附:(其他的一些相关知识)
- 该问题是mysql本身的一个bug,可参考:http://bugs.mysql.com/bug.php?id=30131
- Utf8 4字节各系统的支持情况:
1、windows xp: xp系统不支持4字节utf8字符, 浏览器用占位符显示
2、windows 7: 支持4字节utf8字符
3、mac os x: 支持4字节utf8字符
4、iPhone/iPad: 支持4字节utf8字符
- 如果想支持手机上的表情,可参考:http://my.oschina.net/wingyiu/blog/153357
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的服务端搭建及使用
编 写:袁 亮
时 间: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