原文: http://www.codeceo.com/article/php-mvc-framework-case.html 1 什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。 MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部份分离的同时也赋予了各个基本部分应有的功能。 简而言之, 模型Model – 管理所有数据库相关的逻辑。模型提供了连接和操作数据库的抽象层。 控制器Controller -…
PHP使用CURL详解,CURL实例,CURL爬虫,CURL采集,CURL Restful(POST、GET、PUT、DELETE)
PHP使用CURL详解
Curl是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。
使用方法
使用CURL的PHP扩展完成一个PHP的请求,一般分为四个步骤:
- 初始化Curl连接句柄
- 设置属性选项
- 执行获取结果,处理异常
- 关闭Curl连接句柄
基本结构
(1)初始化 curl_init()
(2)设置变量curl_setopt()
(3)执行并获取结果curl_exec()
(4)释放cURL句柄curl_close()
cURL实现Get和Post
Get方式实现
//初始化 $ch = curl_init(); //设置选项,包括URL curl_setopt($ch, CURLOPT_URL, "http://www.jb51.net"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); //执行并获取HTML文档内容 $output = curl_exec($ch); //释放curl句柄 curl_close($ch); //打印获得的数据 print_r($output);
Post方式实现
$url = "http://localhost/web_services.php"; $post_data = array ("username" => "bob","key" => "12345"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // post数据 curl_setopt($ch, CURLOPT_POST, 1); // post的变量 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); //打印获得的数据 print_r($output);
以上方式获取到的数据是json格式的,使用json_decode函数解释成数组。
$output_array = json_decode($output,true);
如果使用json_decode($output)解析的话,将会得到object类型的数据。
ubuntu下错误的解决
PHP Fatal error: Call to undefined function curl_init() in /var/www/protected/config/functions.php on line 132
在终端命令窗口键入
sudo apt-get install php7.0-curl sudo service apache restart
实例1
更多参看:http://php.net/manual/zh/book.curl.php
实例2 基于CURL的HTTP类库
为什么用curl而不用sock,虽然sock的可塑性的确很强(可封装任何协议的数据包),但curl库相对使用fsockopen我觉得还是有相当多的优点:第一就是抓取效率高,第二就是处理数据和封装简单(因为自己只是用HTTP数据包,用fsockopen就显得不必要了);至于file_get_contents则只是用于简单的抓取数据。以下是详细代码,如果使用中有任何问题都可提出。
<?php /** * 封装基于curl的HTTP类库 * * @file class_httplib.php */ class httplib{ private $response; private $response_header; private $response_data; private $response_info; private $response_httpcode; private $timeout = 30; private $cookie = ''; private $useragent = 'PHP-HttpLib-v1.0'; private $request_header = array(); private $starttime; private $request_proxy = array(); private $request_method; public function __construct(){ $this->starttime = self::_microtime(); //能有效提高POST大于1M数据时的请求速度 $this->set_header('Expect'); } /** * 设置cookie(可选) * @param <array|string> $cookie */ public function set_cookie($cookie = ''){ if (is_array($cookie)){ $cookies = array(); foreach ($cookie as $k => $v){ $cookies[] = $k.'='.$v; } $this->cookie .= implode('; ', $cookies); }else{ $this->cookie .= $cookie; } } /** * 设置用户浏览器信息(可选) * @param string $useragent : 浏览器代理信息 */ public function set_useragent($useragent = ''){ $this->useragent = $useragent; } /** * 设置头部伪造IP(可选),对某些依靠头部信息判断ip的网站有效 * @param string $ip : 需要伪造的ip */ public function set_forgeip($ip){ $this->set_header('CLIENT-IP',$ip); $this->set_header('X-FORWARDED-FOR',$ip); } /** * 添加请求头部信息 * @param string $k * @param string $v */ public function set_header($k,$v = ''){ if (!empty($k)){ $this->request_header[] = $k.':'.$v; } } /** * 设置超时时间(可选) * @param int $sec */ public function set_timeout($sec){ if($sec > ini_get('max_execution_time')) @set_time_limit($sec); $this->timeout = $sec; } /** * 设置代理(可选),如对方限制了ip访问或需要隐藏真实ip * @param string $host :代理服务器(ip或者域名) * @param int $port :代理服务端口 * @param string $user :用户名(如果有) * @param string $pass :用户密码(如果有) */ public function set_proxy($host,$port = '',$user = '',$pass = ''){ $this->request_proxy = array('host'=>$host,'port'=>$port,'user'=>$user,'pass'=>$pass); } /** * 请求url * @param string $url : 请求的地址 * @param <array|string> $postdata :该项如果填写则为POST方式,否则为GET方式;如需上传文件,需在文件路径前加上@符号 * @param string $referer : 来路地址,用于伪造来路 */ public function request($url,$postdata = '',$referer=''){ $ch = $this->_http_request($url,$postdata,$referer); if ($postdata == ''){ $this->request_method = 'GET'; }else{ $this->request_method = 'POST'; } $this->response = curl_exec($ch); if ($this->response === false) { //throw new Exception('cURL resource: ' . (string) $ch . '; cURL error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')'); $this->response_httpcode = 204; //没有内容,请求失败 $this->response_data = 'URL:'.$url.' cURL resource: ' . (string) $ch . '; cURL error: ' . curl_error($ch) . ' (' . curl_errno($ch) . ')'; return false; } $this->_process_response($ch); curl_close($ch); } /** * 获取响应的所有信息 */ public function get_response(){ return $this->response; } /** * 获取响应的header信息 * @param string $key : (可选)header头部信息标示如获取Set-Cookie * @return string */ public function get_header($key = ''){ if ($key == ''){ return $this->response_header; } if (!isset($this->response_header[$key])){ return NULL; } return $this->response_header[$key]; } /** * 获取响应的cookie * @param boolean $assoc : 选择true将返回数组否则返回字符串 */ public function get_cookie($assoc = false){ $cookies = $this->get_header('Set-Cookie'); if ($cookies){ foreach ($cookies as $v){ $cookieinfo = explode(';', $v); if(strpos($this->cookie,$cookieinfo[0]) === FALSE){ $this->cookie .= $cookieinfo[0]; $this->cookie .= '; '; } } } if ($assoc && $this->cookie){ $cookie = substr($this->cookie, 0,-3); $cookie = explode('; ', $cookie); $cookies = array(); foreach ($cookie as $v){ $cookieinfo = explode('=', $v); $cookies[$cookieinfo[0]] = $cookieinfo[1]; } return $cookies; } return $this->cookie; } /** * 获取响应的页面数据即页面代码 */ public function get_data(){ return $this->response_data; } /** * 获取响应的网页编码 */ public function get_charset(){ $content_type = $this->get_header('Content-Type'); if ($content_type) { preg_match('/charset=(.+)/i', $content_type, $matches); if (isset($matches[1])){ return strtoupper(trim($matches[1])); } } return NULL; } /** * 获取连接资源的信息(返回数组) */ public function get_info(){ return $this->response_info; } /** * 获取响应的网页状态码 (注:200为正常响应) */ public function get_statcode(){ return $this->response_httpcode; } /** * 获取请求方法 */ public function get_method(){ return $this->request_method; } /** * 获取请求时间 */ public function get_requesttime(){ return self::_microtime() - $this->starttime; } /** * 处理响应的数据 * @param resource $ch */ private function _process_response($ch = null){ if (is_resource($ch)) { $content_size = curl_getinfo($ch,CURLINFO_CONTENT_LENGTH_DOWNLOAD); if($content_size > 0){ $this->response_header = substr($this->response, 0, -$content_size); $this->response_data = substr($this->response, -$content_size); }else{ $header_size = curl_getinfo($ch,CURLINFO_HEADER_SIZE); $this->response_header = substr($this->response, 0, $header_size); $this->response_data = substr($this->response, $header_size); } $this->response_httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $this->response_info = curl_getinfo($ch); //分解响应头部信息 $this->response_header = explode("\r\n\r\n", trim($this->response_header)); $this->response_header = array_pop($this->response_header); $this->response_header = explode("\r\n", $this->response_header); array_shift($this->response_header); //开头为状态 //分割数组 $header_assoc = array(); foreach ($this->response_header as $header) { $kv = explode(': ', $header); if($kv[0] == 'Set-Cookie'){ $header_assoc['Set-Cookie'][] = $kv[1]; }else{ $header_assoc[$kv[0]] = $kv[1]; } } $this->response_header = $header_assoc; } return false; } /** * 请求数据 * @param string $url * @param string|array $post_data * @param string $referer */ private function _http_request($url,$post_data,$referer=''){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_USERAGENT, $this->useragent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); //强制使用IPV4协议解析域名,否则在支持IPV6的环境下请求会异常慢 @curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); if ($post_data){ curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); } if ($this->cookie){ curl_setopt($ch, CURLOPT_COOKIE, $this->cookie); } if ($referer){ curl_setopt($ch, CURLOPT_REFERER, $referer); } if ($this->request_header){ curl_setopt($ch, CURLOPT_HTTPHEADER, $this->request_header); } if ($this->request_proxy) { curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); $host = $this->request_proxy['host']; $host .= ($this->request_proxy['port']) ? ':' . $this->request_proxy['port'] : ''; curl_setopt($ch, CURLOPT_PROXY, $host); if (isset($this->request_proxy['user']) && isset($this->request_proxy['pass'])) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->request_proxy['user'] . ':' . $this->request_proxy['pass']); } } return $ch; } private static function _microtime(){ return array_sum(explode(' ', microtime())); } }
用法:
<?php include 'httplib.class.php'; //初始化 $http = new httplib(); //设置超时时间为60秒 $http->set_timeout(60); //设置浏览器信息 $http->set_useragent($_SERVER['HTTP_USER_AGENT']); //设置请求的方式为XMLHttpRequest,模拟ajax请求信息,可用于某些api的限制,此处仅为演示说明 $http->set_header('X-Requested-With','XMLHttpRequest'); //设置代理服务器信息 $http->set_proxy('59.108.116.175','3128'); //请求资源 $http->request('http://www.baidu.com/s?wd=ip'); //获取网页数据 $data = $http->get_data(); //获取cookie(默认返回字符串,参数为true时返回数组) $cookie = $http->get_cookie(); //获取网页响应状态码 $statcode = $http->get_statcode(); //获取原始未处理的响应信息 $response = $http->get_response(); //获取连接资源的信息(返回数组),如平均上传速度 、平均下载速度 、请求的URL等 $response_info = $http->get_info();
实例3 抓取的网页
在我们写 SOA 服务化项目的时候, 总是要定义许多 API 接口为功能提供服务, 那么这个时候 cURL 就发挥了它巨大的作用. 这里分享一下自己封装的 cURL 方法
<?php /** * @param $url 请求网址 * @param bool $params 请求参数 * @param int $ispost 请求方式 * @param int $https https协议 * @return bool|mixed */ public static function curl($url, $params = false, $ispost = 0, $https = 0) { $httpInfo = array(); $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if ($https) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在 } if ($ispost) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_URL, $url); } else { if ($params) { if (is_array($params)) { $params = http_build_query($params); } curl_setopt($ch, CURLOPT_URL, $url . '?' . $params); } else { curl_setopt($ch, CURLOPT_URL, $url); } } $response = curl_exec($ch); if ($response === FALSE) { //echo "cURL Error: " . curl_error($ch); return false; } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpInfo = array_merge($httpInfo, curl_getinfo($ch)); curl_close($ch); return $response; }
使用方法:
<?php // 发送请求 $result = self::curl('网址', '参数', true); // 收到的数据需要转化一下 $json = json_decode($result);
实例4 CURL类(POST、GET、PUT、DELETE)
调整版PHP的CURL类(POST、GET、PUT、DELETE)
因为经常用到所以研究了下重新自己写了个比较完整的,至少满足自己平常的需求。
<?php /** * @param $URL 请求链接 * @param null $data 数据 array() string * @param string $type 请求类型 POST GET PUT DELETE * @param string $headers 头部信息 * @param string $data_type 返回数据类型 默认为json * @return mixed */ function callInterfaceCommon($URL,$data=null,$type='POST',$headers="",$data_type='json'){ $ch = curl_init(); //判断ssl连接方式 if(stripos($URL, 'https://') !== false) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSLVERSION, 1); } $connttime=300; //连接等待时间500毫秒 $timeout = 15000;//超时时间15秒 $querystring = ""; if (is_array($data)) { // Change data in to postable data foreach ($data as $key => $val) { if (is_array($val)) { foreach ($val as $val2) { $querystring .= urlencode($key).'='.urlencode($val2).'&'; } } else { $querystring .= urlencode($key).'='.urlencode($val).'&'; } } $querystring = substr($querystring, 0, -1); // Eliminate unnecessary & } else { $querystring = $data; } // echo $querystring; curl_setopt ($ch, CURLOPT_URL, $URL); //发贴地址 //设置HEADER头部信息 // if($headers!=""){ // curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers); // }else { // curl_setopt ($ch, CURLOPT_HTTPHEADER, array('Content-type: text/json')); // } curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);//反馈信息 curl_setopt ($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); //http 1.1版本 curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT_MS, $connttime);//连接等待时间 curl_setopt ($ch, CURLOPT_TIMEOUT_MS, $timeout);//超时时间 switch ($type){ case "GET" : curl_setopt($ch, CURLOPT_HTTPGET, true);break; case "POST": curl_setopt($ch, CURLOPT_POST,true); curl_setopt($ch, CURLOPT_POSTFIELDS,$querystring);break; case "PUT" : curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($ch, CURLOPT_POSTFIELDS,$querystring);break; case "DELETE":curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($ch, CURLOPT_POSTFIELDS,$querystring);break; } $file_contents = curl_exec($ch);//获得返回值 // echo time().'<br>'; $status = curl_getinfo($ch); //dump($status); curl_close($ch); if($data_type=="json"||$data_type=="JSON") { return json_encode($file_contents); }else { return $file_contents; } }
stackoverflow
/** * @desc Do a DELETE request with cURL * * @param string $path path that goes after the URL fx. "/user/login" * @param array $json If you need to send some json with your request. * For me delete requests are always blank * @return Obj $result HTTP response from REST interface in JSON decoded. */ public function curl_del($path, $json = '') { $url = $this->__url.$path; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); $result = json_decode($result); curl_close($ch); return $result; }
或者
function CallAPI($method, $api, $data) { $url = "http://localhost:82/slimdemo/RESTAPI/" . $api; $curl = curl_init($url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); switch ($method) { case "GET": curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET"); break; case "POST": curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); break; case "PUT": curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); break; case "DELETE": curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); break; } $response = curl_exec($curl); $data = json_decode($response); /* Check for 404 (file not found). */ $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); // Check the HTTP Status code switch ($httpCode) { case 200: $error_status = "200: Success"; return ($data); break; case 404: $error_status = "404: API Not found"; break; case 500: $error_status = "500: servers replied with an error."; break; case 502: $error_status = "502: servers may be down or being upgraded. Hopefully they'll be OK soon!"; break; case 503: $error_status = "503: service unavailable. Hopefully they'll be OK soon!"; break; default: $error_status = "Undocumented error: " . $httpCode . " : " . curl_error($curl); break; } curl_close($curl); echo $error_status; die; }
CALL Delete Method
$data = array('id'=>$_GET['did']); $result = CallAPI('DELETE', "DeleteCategory", $data);
CALL Post Method
$data = array('title'=>$_POST['txtcategory'],'description'=>$_POST['txtdesc']); $result = CallAPI('POST', "InsertCategory", $data);
CALL Get Method
$data = array('id'=>$_GET['eid']); $result = CallAPI('GET', "GetCategoryById", $data);
CALL Put Method
$data = array('id'=>$_REQUEST['eid'],m'title'=>$_REQUEST['txtcategory'],'description'=>$_REQUEST['txtdesc']); $result = CallAPI('POST', "UpdateCategory", $data);
本文:PHP使用CURL详解,CURL实例,CURL爬虫,CURL采集,CURL Restful(POST、GET、PUT、DELETE)