/*
*编 写:袁 亮
*时 间:2013-02-27
*功 能:常见的两种缩略图生成策略实现,图片不允许变形,在生成缩略图之前需要确保图片存放目录存在并有写权限
可以调用createDirs创建目录并赋予相应的权限,该函数支持多级目录
在window下测试时处理大图片可能会出现内存不足,可以使用ini_set('memory_limit', '12M');更改内存限制
*/
function createDirs($dir,$model=0777){//创建多级目录
return is_dir($dir) or createDirs(dirname($dir),$model) and mkdir($dir,$model);
}
/*
*生成一张给定宽高的缩略图,超出部分进行居中截图,只支持jpg,gif,png格式,生成的是jpg格式图片
@old_src:源图地址
@new_src:缩略图地址
@new_width:缩略图宽
@new_height:缩略图高
@rate:图片质量,0-100,可选参数,默认100
#返回值:1:缩略图生成成功,-1:不支持该图片类型,-2:图片文件错误,-3:缩略图生成失败
*/
function cutPhotoDesign($old_src,$new_src,$new_width,$new_height,$rate=100){
$old_info = getimagesize($old_src);
switch($old_info[2]){
case 1:$im = imagecreatefromgif($old_src);break;
case 2:$im = imagecreatefromjpeg($old_src);break;
case 3:$im = imagecreatefrompng($old_src);break;
default:return -1;
}
if(!$im){
return -2;
}
$old_width = imagesx($im);
$old_height = imagesy($im);
if($old_width<=$new_width && $old_height<=$new_height){//图片过小,直接原图显示
$res = copy($old_src,$new_src);
imagedestroy($im);
return $res?1:-3;
}
$x_rate = $old_width/$new_width;//计算压缩图片尺寸,以及截图开始位置
$y_rate = $old_height/$new_height;
if($x_rate<$y_rate){//宽度优先压缩
$dst_x = $new_width;
$dst_y = ceil($old_height/$x_rate);
$new_start_x = 0;
$new_start_y = ($dst_y-$new_height)/2;
}else{//高度优先压缩
$dst_x = ceil($old_width/$y_rate);
$dst_y = $new_height;
$new_start_x = ($dst_x-$new_width)/2;
$new_start_y = 0;
}
$newim = imagecreatetruecolor($dst_x,$dst_y);//等比例压缩图片,将图片的宽或者高压缩到指定参数
imagecopyresampled($newim,$im,0,0,0,0,$dst_x,$dst_y,$old_width,$old_height);
$cutim = imagecreatetruecolor($new_width,$new_height);//将宽高都固定成指定参数,超出的部分居中截图
imagecopyresampled($cutim,$newim,0,0,$new_start_x,$new_start_y,$new_width,$new_height,$new_width,$new_height);
$res = imagejpeg($cutim,$new_src,$rate);//对图像进行截图
imagedestroy($im);
imagedestroy($newim);
imagedestroy($cutim);
return $res?1:-3;
}
/*
*生成一张宽高不超过给定参数的缩略图,只支持jpg,gif,png格式,生成的是jpg格式图片
@old_src:源图地址
@new_src:缩略图地址
@new_width:缩略图宽
@new_height:缩略图高
@rate:图片质量,0-100,可选参数,默认100
#返回值:1:缩略图生成成功,-1:不支持该图片类型,-2:图片文件错误,-3:缩略图生成失败
*/
function cutPhoto($old_src,$new_src,$new_width,$new_height,$rate=100){
$old_info = getimagesize($old_src);
switch($old_info[2]){
case 1:$im = imagecreatefromgif($old_src);break;
case 2:$im = imagecreatefromjpeg($old_src);break;
case 3:$im = imagecreatefrompng($old_src);break;
default:return -1;
}
if(!$im){
return -2;
}
$old_width = imagesx($im);
$old_height = imagesy($im);
if($old_width<=$new_width && $old_height<=$new_height){//图片过小,直接原图显示
$res = copy($old_src,$new_src);
imagedestroy($im);
return $res?1:-3;
}
$x_rate = $old_width/$new_width;//计算缩略图实际尺寸
$y_rate = $old_height/$new_height;
if($x_rate<$y_rate){
$dst_x = ceil($old_width/$y_rate);
$dst_y = $new_height;
}else{
$dst_x = $new_width;
$dst_y = ceil($old_height/$x_rate);
}
$newim = imagecreatetruecolor($dst_x,$dst_y);//按实际大小生成一张画布
$bg = imagecolorallocate($newim,255,255,255);//白色背景
imagecopyresampled($newim,$im,0,0,0,0,$dst_x,$dst_y,$old_width,$old_height);//将图片内容复制到新画布中
$res = imagejpeg($newim,$new_src,$rate);//将画布中的内容写入文件
imagedestroy($im);
imagedestroy($newim);
return $res?1:-3;
}
php类初阶:简单使用
编 写:袁 亮
时 间:2015-07-13
说 明:php类初阶,简单使用
一、为什么需要使用类?
1、当项目比较复杂,代码量过大,我们会将两种代码给封装成函数:
1.1 一种是好多地方重复使用的
1.2 一种是逻辑比较复杂,不想跟其他代码混在一块
2、当项目更加庞大的时候,使用函数还是不能很好的组织代码,这个时候,我们会希望通过类来处理
比如对数据库,可能有10几种操作,每种操作都可以封装成一个函数,但是各个函数又都是针对的数据库做的处理
这个时候,我们会希望将对数据库的所有操作都封装成一个类,这个类里有各种各样的函数做不同的处理
这个类本身又有一些公共的变量,可以在这些函数内部使用
二、简单范例
//类定义
class Mysqls{
public $_dblink;//类中的公共变量
function __construct(){//构造方法,在类实例化时将自动执行
$this->_dblink = '';
}
//执行一条sql
function query($sql){
return mysql_query($sql,$this-_dblink);//使用类中的成员变量
}
//从数据库中获取一行数据
function getRow($sql){
$query = $this->query($sql);//调用类中的成员函数
//后续处理
}
//从数据库中获取多行数据
function getRows($sql){
}
}
$ms = new Mysqls;//实例化一个类,得到一个对象
$data = $ms->getRow($sql);//调用对象中的成员函数
var_dump($data);
die();
三、使用
1、命名规范请点此参考
类名、函数名、变量名
2、使用$this来调用成员函数和成员变量
3、成员变量,以_开头命名
四、目标:
1、能自己写一个简单的类,并使用
2、理解类、对象、实例化的差异
类:定义的一类特殊数据结构,一种抽象
对象:符合一类规则的某个具体数据
实例化:根据某个类,具体到一个对象的过程,交实例化
3、一个类,可以实例化多个对象,各个对象之间独立(静态变量例外,后期自己了解),可以自己写代码测试下
根据网址,将完整网页保存为图片
@徐同同 @姚钦元
一、要求:
1、有多个网址,需要每天定时将这些网页的内容保存为完整的jpg图片
2、不要人工参与,程序定时自动抓取
3、保存图片的效果,可以参考360浏览器的保存完整网页为图片功能
4、时间:周四下班前,告知我结果
钱昱成:对博客频道要比我熟悉
一、具体要求
1、用户的主要操作,分别在哪,怎么操作,有什么限制
2、编辑后台主要操作,分别在哪看,哪些能用,哪些不能用,有什么注意事项
3、以上这些,都需要的是文档记录的方式
4、时间:下周一前
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 );//跳转次数限制,防止死循环等
curl阶段一:简单使用
编 写:袁 亮
时 间:2015-07-09
说 明:curl的初阶使用
一、curl是干什么的?
当我们需要在程序中,抓取其他网页或者图片等远程数据的时候,可以使用curl完成一些比较强大的功能
ps:如果要求不高,只是简单的抓取,可以使用file_get_contents来抓取
二、开启扩展
ps:确定是否有该扩展,很简单,写个php文件,里面价格curl_init();运行是否报错,如果报错则需要开启扩展
1、windows下开启,以appserv为例
1.1 将以下三个文件复制到C:\Windows\system32\下
AppServ\php5\ext\php_curl.dll
AppServ\php5\libeay32.dll
AppServ\php5\ssleay32.dll
1.2 找到C:\Windows\php.ini文件(phpinfo函数输出的内容中,有php.ini文件的位置)
extension=php_curl.dll
将这行前面的;号注释去掉
1.3 重启apache,appserv中有apache restart的功能
2、linux
虚拟机上的话重新编译php的curl模块
线上服务器,直接找运维同学帮忙安装即可
三、简单使用
1、简单函数
function curl($url){//curl模拟浏览器方式数据
$urlinfo = parse_url($url);
$host = $urlinfo["scheme"].'://'.$urlinfo['host'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不直接输出,作为变量返回
curl_setopt($ch, CURLOPT_REFERER, $host);//模拟referer,防止被禁止,抓取图片的时候非常有用
curl_setopt($ch, CURLOPT_TIMEOUT,3);//内容传输的最长时间,一定要设置
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,3);//连接的最长时间,一定要设置
$img = curl_exec($ch);
return $img;
}
2、使用
$html = curl('网页、图片等地址');
基本正则表达式能力
编 写:袁 亮
时 间:2015-07-07
说 明:基本正则能力
一、什么是正则表达式?
1、概念:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合
组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑
2、见到的说,就是用一个简单的字符串来匹配一定规则的一类字符串,来达到筛选或者验证字符串是否是我们所需要的字符串格式
二、几个简单例子:
1、匹配用户名:
1.1 代码
[code]
$str = 'yuanliang847';
preg_match('/^[a-z][\w_]{3,19}$/',$str);
[/code]
1.2 正则表达式:/^[a-z][\w_]{3,19}$/
这个正则匹配出来的是:第一个是小写字母,后面有3-19个,小写字母、大写字母、数字或者_组成
后面没有其他字符的字符串
前后的//表示这里面是一个正则表达式
^:表示从字符串最开始匹配
[]:表示只要符合其中一个就满足,a-z代表从小写a到小写的z
\w:代表小写字母或者大写字母或者数字,_这个就代表_本身
{3,19}:代表其前面的内容重复3到19次
$:代表字符串结束,后面不允许跟着其他内容
2、匹配手机号
2.1 表达式
/^1[0-9]{10}$/
2.2 说明:
第一个字符必须是1,后面跟着10位0-9的数字
3、匹配邮寄地址
3.1 表达式
/^[\w]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/
3.2 说明
最开始1到多个大小写字母或者数字
后面可以有0或者多个(.跟着1到多个大小写字母、数字、中划线-)
后面必须有一个@符合
后面有1到多个大小写字母、数字、-组成的字符串
最后必须是以一到多个(.跟着多个大小写字母、数字、-组成)
三、其他
1、正则表达式非常重要,在很多地方都有用到,各语言都支持
2、在实际工作中,变查边学,如果不是经常用到,只需要掌握简单的即可
3、大部分的正则网上都很容易找到,这个阶段,追求能看懂别人写的,并做一些简单的调整即可
4、有兴趣的,可以参考后续的博客,我会慢慢整理
php的输出方法总结
编 写:袁 亮
时 间:2015-07-07
说 明:php的输出方法总结
一、必须掌握
1、echo
1.1 没什么说的,第一个就要学会,网页内容输出都是使用的这个
1.2 缺点:只能输出字符串,不能输出一些复杂的数据结构
2、var_dump
2.1 调试的时候,首选,不管是什么类型的数据,都能打印输出
2.2 调试的时候,经常会跟die连在一块
2.3 需要注意,当数组太大的时候,会被截断,可以通过设置php参数来调整
3、var_export
3.1 类似var_dump,输出的是合法的php代码
3.2 可以补抓输出内容,在适当的地方在重新输出,$str = var_export($data,true);
3.3 输出的内容,可以复制过来,直接作为php数组使用,很多时候做文件缓存会用,很有用
3.4 可以打印调试各种类型数据,而且不会被截断
二、了解
1、print
1.1 类似echo,只能输出字符串
1.2 不怎么使用,了解即可
2、printf
2.1 输出格式化的字符串
2.2 不常用
2.3 类似:sprintf vprintf 等等,有兴趣可以看下
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使用