Tips:这里讨论的都是百万级,千万级,亿万级的大数据,而且是生产环境条件下的问答。
//根据条件,每批执行100个,如果你的数据库够强悍,数值可以调大 //无限循环执行,直到执行完毕! //每次都从0开始分页,从而巧妙的避免了当Mysql的OFFSET值过大导致分页慢的性能问题 $sql = 'SELECT `id`, `text` FROM `table` WHERE `state` = 0 LIMIT 0, 100'; while(!($result = $db->fetchAll($sql))){ foreach($result as $k => $v){ echo 'k:'.$k.PHP_EOL.'v:'.$v.PHP_EOL; $db->update('table', array('state' => 1), 'id = '.$k.'');//将已执行的标记为1 //insert db where id = '.$v['id'].'... //update db where id = '.$v['id'].'... //delete db where id = '.$v['id'].'... //mail();//发送邮件给用户... usleep(mt_rand(1000, 1000000));//随机间歇休息一时,防止服务器卡死 } } echo '执行完毕!'; exit();
$flag = false; while(!$flag){ $content = curl('http://my.oschina.net/cart/'); if(stripos($content, '你指定的识别是否采集到你想要的内容的字符串') !== false){ $flag = true; } } echo $flag ? '哈哈,我抓到你啦.' : '采集失败!'; exit();
//更形象的模拟浏览器,代码如下: //必选:开启session @session_start(); //必选:模拟cookie curl_setopt($curl, CURLOPT_COOKIEJAR, getcwd().'/cookies.txt'); curl_setopt($curl, CURLOPT_COOKIEFILE, getcwd().'/cookies.txt'); curl_setopt($curl, CURLOPT_COOKIE, session_name().'='.session_id().'; a=1; b=2; c=3'); //必选:模拟浏览器 curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/'.mt_rand(1, 9).'.0 (Windows NT '.mt_rand(1, 9).'.'.mt_rand(1, 9).'; rv:'.mt_rand(1, 100).'.'.mt_rand(1, 9).') Gecko/20100101 Firefox/'.mt_rand(1, 9).'0.'.mt_rand(1, 9).''); //必选:模拟访客IP、header等真实请求信息 curl_setopt($curl, CURLOPT_HTTPHEADER, array ( 'Accept: text/html,application/xhtml+xml,application/xml;q=0.'.mt_rand(1, 9).',*/*;q=0.'.mt_rand(1, 9).'', 'Accept-Language: en-us,en;q=0.'.mt_rand(1, 9).'', 'Cache-Control: max-age=0', 'Connection: keep-alive', 'Pragma: no-cache', 'X-Forwarded-For: '.mt_rand(0, 255).'.'.mt_rand(0, 255).'.'.mt_rand(0, 255).'.'.mt_rand(0, 255), 'Client_Ip: '.mt_rand(0, 255).'.'.mt_rand(0, 255).'.'.mt_rand(0, 255).'.'.mt_rand(0, 255), )); //可选项:更高级的用户可使用代理采集 curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_setopt($curl, CURLOPT_PROXY, '127.0.0.1:8080');//代理ip自己去搜索引擎搜 //必选:更真实的用户行为 usleep(mt_rand(1000000, 3000000));//随机间歇休息一时 //把上述代码加到执行采集curl_exec($curl)前面即可! //切记:执行curl_exec($curl) 和 上述代码的次数一定是一样的! //也就是说,每次开始新的抓取curl_exec($curl)前,必须再次加载上述代码!原因自己想^.^
$arr = array(1, 2, 3, 4); foreach ($arr as &$value) { $value = $value * 2; } // $arr is now array(2, 4, 6, 8) unset($value); // 最后取消掉引用
SELECT `name` FROM `name` AS t1 JOIN ( SELECT ROUND( RAND( ) * ( ( SELECT MAX( id ) FROM `name` ) - ( SELECT MIN( id ) FROM `name` ) ) + ( SELECT MIN( id ) FROM `name` ) ) AS id ) AS t2 WHERE t1.id >= t2.id ORDER BY t1.id LIMIT 5
//strip_tags:替代方案 class PHP { public static function strip_tags(&$str, $default = false){ return filter_var($str, FILTER_SANITIZE_STRING, array('options' => array('default' => $default))); } } var_dump(PHP::strip_tags('这里是不完整的HTML标签或者单引号、双引号没有成对出现。。。')); //ip2long:替代方案 class PHP { public static function ip2long(&$ip){ return sprintf('%u', ip2long($ip)); } } var_dump(PHP::ip2long('192.168.1.1')); //nl2br:替代方案 class PHP { public static function nl2br(&$str){ return str_replace(array("\r\n", "\r", "\n"), ' ', $str); } } var_dump(PHP::nl2br('h ello')); //crc32:替代方案 class PHP { public static function crc32(&$url){ return sprintf('%u', crc32($url)); } } var_dump(PHP::crc32('http://my.oschina.net/cart/'));
const SPIDER_URL = 'http://my.oschina.net/cart/'; const SPIDER_CATEGORY_LIST = array(1,2,3); const SPIDER_CATEGORY_ID = 118;
@ini_set('date.timezone','PRC');
//假设你的库文件目录 E:\php\data\library //你的当前执行的index.php文件目录 E:\php\data\localweb\tools //那么,你在E:\php\data\localweb\tools\index.php //可加入以下代码,就直接可以使用你的类库了,无include,无require,APC下,性能更卓越! //智能加载 function autoload($class) { set_include_path('../../library/'); spl_autoload($class); } spl_autoload_register('autoload'); /////////////////////////////////////////// echo 'Hello,word!'; echo Tools::formatUrl('http://my.oschina.net/cart/'); $tools = new Tools(); var_dump($tools->info());
array_column【PHP 5.5.0+】
array_map
array_walk
var_dump(array_column(array(array('id' => '1','address' => '127.0.0.1:8080'),array('id' => '2','address' => '127.0.0.1:9090')), 'address', 'id'));
PHP ZIP扩展【PHP 5.2.0+】
//在线解压 function ZipExtract($from_file, $to_dir){ if (!is_dir($to_dir)){ mkdir($to_dir, 0777); } $zip = new ZipArchive(); if ($zip->open($from_file) === true && $zip->extractTo($to_dir) && $zip->close()){ return true; } return false; } //压缩打包 $zip = new ZipArchive(); $ret = $zip->open('application.zip', ZipArchive::OVERWRITE); if ($ret !== TRUE) { printf('Failed with code %d', $ret); } else { $options = array('add_path' => 'sources/', 'remove_all_path' => TRUE); $zip->addGlob('*.{php,txt}', GLOB_BRACE, $options); $zip->close(); }
str_replace(array('a', 'b', 'c'), array('aa', 'bb', 'cc'), $str); str_replace(array(123, 456, 789), array(11, 22, 33), $str); str_replace(array('/(\d+)/isu', 'a', 'b'), array('数字被正则替换了', '普通替换A', '普通替换B'), $str);
尽管你设置了以下代码 //PHP文件本身编码 @ini_set('default_charset', 'utf-8'); //数据库编码 $db = new Db('mysql:host=localhost;dbname=spider', 'root', '123', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
现象: 导致了我们看到的文件只存入一半,数据库longtext类型丢失内容的现象 解决方法分2种: 1.因为大文件内容中有些非utf8字符导致入库失败,需要针对你入库的字符串进行强制转码: iconv('utf-8', "utf-8//IGNORE", $data); 或者 mb_convert_encoding($string, 'utf-8', 'utf-8'); 2.数据库字段编码的utf8_general_ci改为utf8mb4_general_ci,如emoji表情符号,就是4字节!
SELECT `id` , `url` , `content` FROM product INNER JOIN (SELECT `id` FROM product ORDER BY `id` LIMIT 10000 , 100) AS product2 USING ( id );
//原理:一般网站,当你访问1个不存在的目录分页时,都会展示最后1个分页内容,从而提取最后1页的分页数目 //操作: //采集1个非常大的分页数值的分页URL,如:http://www.xxx.com/p/100000 //然后根据采集的内容从中提取最后一页的分页数字
//数据库必须是innodb类型 //使用事务+执行标记do来实现我们的需求 $db->beginTransaction();//开启事务 $sql = 'SELECT `id`, `url`, `content` FROM `table` WHERE `do` = 0 LIMIT 0, 100 FOR UPDATE';//获取未执行的记录 $urlArray = $db->fetchAll($sql); $times = 1; while(!empty($urlArray)){ foreach($urlArray as $v){ //do somthing.... $db->update('table', array('do' => 1, 'url' => $v['url']), '`id` = ' . $v['id']);//已执行 echo $v['id'].' OK. '.PHP_EOL; } //递归中 提交事务 if(!$db->commit()){ $db->rollBack(); echo '['.$times.']. Times OK.'.PHP_EOL; }else{ echo '['.$times.']. Times No...'.PHP_EOL; } //递归中 开始事务 $db->beginTransaction(); $urlArray = $db->fetchAll($sql); $times++; } //提交事务 if(!$db->commit()){ $db->rollBack(); echo 'OK.'.PHP_EOL; }else{ echo 'No...'.PHP_EOL; } echo '协同办公,执行完毕!';
echo join('.', array(mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)));
$db->query('INSERT INTO `myTable` (`address`) VALUES '.join(',', array_map(function($ip, $port){return '("'.($ip.':'.$port).'")';}, $ipArray[0], $ipArray[1])).';'); 注意,你的$ipArray数据格式为: $ipArray = array(array('127.0.0.1','192.168.1.1'), array('80','443'));
usleep(mt_rand(1000, 1000000));//单位是微妙
//1.定义文件名 //2.判断文件存不存在 //3.如果存在,则引用文件 //4.如果不存在,则输出退出语句 (is_file($configFile = 'config.inc.php') && require($configFile)) || exit('The configuration file "'.$configFile.'" does not exist!');
http://127.0.0.1/?a[]=1&a[]=2&a[]=3 //这也给我们提了个醒,get等外部提交来的参数的值除了常规的字符串、空、null,还有数组!记得过滤、限制即可,如: //is_string($_GET['a']) //is_array($_GET['a']) //(string)$_GET['a']