Table des matières
代理开始批量验证中,整个过程将会花费您几分钟时间。

多线程的cURL

Jul 25, 2016 am 08:49 AM

本处是一个可以灵活的多线程的调用 cURL的。
这里跟php手册 http://us2.php.net/manual/zh/function.curl-multi-select.php 中提供的样例不同,代码执行效率要高不少
本处两个文件,一个是muti_curl的文件,里面包含两个class
一个是运用的方法,这里是批量检查代理ip是否可用
  1. class request_setting {
  2. public $url = false;
  3. public $method = 'GET';
  4. public $post_data = null;
  5. public $headers = null;
  6. public $options = null;
  7. function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
  8. $this->url = $url;
  9. $this->method = $method;
  10. $this->post_data = $post_data;
  11. $this->headers = $headers;
  12. $this->options = $options;
  13. }
  14. public function __destruct() {
  15. unset($this->url, $this->method, $this->post_data, $this->headers, $this->options);
  16. }
  17. }
  18. /***********************************************************************************************
  19. 批量操作的类
  20. *******************************************************************************************/
  21. class muti_curl {
  22. protected $thread_size = 100;
  23. protected $timeout = 30;
  24. private $callback;
  25. protected $options = array(
  26. CURLOPT_SSL_VERIFYPEER => false,//禁用后cURL将终止从服务端进行验证。使用CURLOPT_CAINFO选项设置证书使用CURLOPT_CAPATH选项设置证书目录 如果CURLOPT_SSL_VERIFYPEER(默认值为2)被启用,CURLOPT_SSL_VERIFYHOST需要被设置成TRUE否则设置为FALSE。 自cURL 7.10开始默认为TRUE。从cURL 7.10开始默认绑定安装。
  27. CURLOPT_RETURNTRANSFER => true, //将 curl_exec()获取的信息以文件流的形式返回,而不是直接输
  28. CURLOPT_CONNECTTIMEOUT => 15,
  29. CURLOPT_TIMEOUT => 30,
  30. // CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_0, //使用代理的时候用这个去抓取数据,更爽
  31. // CURLOPT_AUTOREFERER=>false,// 当根据Location:重定向时,自动设置header中的Referer:信息。
  32. // CURLOPT_BINARYTRANSFER=>false, //在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出这个不用设置。
  33. // CURLOPT_COOKIESESSION=>true,// 启用时curl会仅仅传递一个session cookie,忽略其他的cookie,默认状况下cURL会将所有的cookie返回
  34. // CURLOPT_CRLF=>false,// 启用时将Unix的换行符转换成回车换行符。
  35. // CURLOPT_DNS_USE_GLOBAL_CACHE=>false, // 启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认启用。
  36. // CURLOPT_FAILONERROR=>false, // 显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息。
  37. // CURLOPT_FILETIME=>true, //启用时会尝试修改远程文档中的信息。结果信息会通过 curl_getinfo()函数的CURLINFO_FILETIME选项返回。 curl_getinfo().
  38. // CURLOPT_FOLLOWLOCATION=>false, // 启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
  39. // CURLOPT_FORBID_REUSE=>true, //在完成交互以后强迫断开连接,不能重用。
  40. // CURLOPT_FRESH_CONNECT=>true,// 强制获取一个新的连接,替代缓存中的连接。
  41. // CURLOPT_FTP_USE_EPRT=>false,// 启用时当FTP下载时,使用EPRT (或 LPRT)命令。设置为FALSE时禁用EPRT和LPRT,使用PORT命令 only.
  42. // CURLOPT_FTP_USE_EPSV=>false,// 启用时,在FTP传输过程中回复到PASV模式前首先尝试EPSV命令。设置为FALSE时禁用EPSV命令。
  43. // CURLOPT_FTPAPPEND=>false,// 启用时追加写入文件而不是覆盖它。
  44. // CURLOPT_FTPASCII=>false,// CURLOPT_TRANSFERTEXT的别名。
  45. // CURLOPT_FTPLISTONLY=>false,// 启用时只列出FTP目录的名字。
  46. // CURLOPT_HEADER=>true,// 启用时会将头文件的信息作为数据流输出。
  47. // CURLINFO_HEADER_OUT=>false, //启用时追踪句柄的请求字符串。
  48. // CURLOPT_HTTPGET=>true,// 启用时会设置HTTP的method为GET,因为GET是默认是,所以只在被修改的情况下使用。
  49. // CURLOPT_HTTPPROXYTUNNEL =>true,// 启用时会通过HTTP代理来传输。
  50. // CURLOPT_MUTE=>true,// 启用时将cURL函数中所有修改过的参数恢复默认值。
  51. // CURLOPT_NETRC=>false,// 在连接建立以后,访问~/.netrc文件获取用户名和密码信息连接远程站点。
  52. // CURLOPT_NOBODY=>true, 启用时将不对HTML中的BODY部分进行输出。
  53. // CURLOPT_NOPROGRESS=>false,//启用时关闭curl传输的进度条,此项的默认设置为启用。
  54. // CURLOPT_NOSIGNAL=>false,// 启用时忽略所有的curl传递给php进行的信号。在SAPI多线程传输时此项被默认启用。 cURL 7.10时被加入。
  55. // CURLOPT_POST=>false,// 启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。
  56. // CURLOPT_PUT=>false,// 启用时允许HTTP发送文件,必须同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE。
  57. // CURLOPT_TRANSFERTEXT=>false,// 启用后对FTP传输使用ASCII模式。对于LDAP,它检索纯文本信息而非HTML。在Windows系统上,系统不会把STDOUT设置成binary模式。
  58. // CURLOPT_UNRESTRICTED_AUTH=>true,// 在使用CURLOPT_FOLLOWLOCATION产生的header中的多个locations中持续追加用户名和密码信息,即使域名已发生改变。
  59. // CURLOPT_UPLOAD=>false,// 启用后允许文件上传。
  60. // CURLOPT_VERBOSE =>true,// 启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中。
  61. );
  62. private $headers = array();
  63. private $requests = array();
  64. private $requestMap = array();
  65. /*********************
  66. 构造一个callback的函数
  67. ********************/
  68. function __construct($callback = null) {
  69. $this->callback = $callback;
  70. }
  71. /********************************************************************
  72. 重载 __get的方法
  73. *******************************************************************/
  74. public function __get($name) {
  75. return (isset($this->{$name})) ? $this->{$name} : null;
  76. }
  77. /*********************************************************************
  78. 重载 __set的方法
  79. *******************************************************/
  80. public function __set($name, $value) {
  81. // 增加一个设置到headers
  82. if ($name == "options" || $name == "headers") {
  83. $this->{$name} = $value + $this->{$name};
  84. } else {
  85. $this->{$name} = $value;
  86. }
  87. return true;
  88. }
  89. //增加一个请求
  90. public function add($request) {
  91. $this->requests[] = $request;
  92. return true;
  93. }
  94. public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
  95. $this->requests[] = new request_setting($url, $method, $post_data, $headers, $options);
  96. return true;
  97. }
  98. public function get($url, $headers = null, $options = null) {
  99. return $this->request($url, "GET", null, $headers, $options);
  100. }
  101. public function post($url, $post_data = null, $headers = null, $options = null) {
  102. return $this->request($url, "POST", $post_data, $headers, $options);
  103. }
  104. private function single_curl() {
  105. $ch = curl_init(); //初始化
  106. $request = array_shift($this->requests);//把第一个单元移出并作为结果
  107. $options = $this->get_options($request);//获得该单元的设置
  108. curl_setopt_array($ch, $options);//批设置
  109. $output = curl_exec($ch);
  110. $curl_info = curl_getinfo($ch);
  111. if ($this->callback) {
  112. $callback = $this->callback;
  113. if (is_callable($this->callback)) {
  114. call_user_func($callback, $output, $curl_info, $request);
  115. }
  116. }
  117. else
  118. return $output;
  119. return true;
  120. }
  121. private function rolling_curl($thread_size = null) {
  122. if ($thread_size){
  123. $this->thread_size = $thread_size;
  124. }
  125. if (count($this->requests) thread_size){
  126. $this->thread_size = count($this->requests);
  127. }
  128. if ($this->thread_size $errorinfo = '线程大小必须大于 1!!!!';
  129. throw new Exception($errorinfo);
  130. }
  131. $queue = curl_multi_init();
  132. //在线程里开始增加任务队列
  133. for ($i = 0; $i thread_size; $i++) {
  134. $ch = curl_init();
  135. $options = $this->get_options($this->requests[$i]);
  136. curl_setopt_array($ch, $options);//获得设置
  137. curl_multi_add_handle($queue, $ch);//添加进去
  138. $key = (string) $ch;
  139. $this->requestMap[$key] = $i;
  140. }
  141. do {
  142. while (($statu_run_muti_exec = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ;
  143. if ($statu_run_muti_exec != CURLM_OK){ break; }
  144. // 发现完成的一个请求,进行处理
  145. while ($done = curl_multi_info_read($queue)) {
  146. $curl_info = curl_getinfo($done['handle']);
  147. $output = curl_multi_getcontent($done['handle']);
  148. $callback = $this->callback;
  149. if (is_callable($callback)){
  150. $key = (string) $done['handle'];
  151. $request = $this->requests[$this->requestMap[$key]];
  152. unset($this->requestMap[$key]);//这个销毁变量用得很帅
  153. call_user_func($callback, $output, $curl_info, $request);
  154. }
  155. //增加一个未处理的请求加入到一个已经完成的队列中
  156. if ($i requests) && isset($this->requests[$i]) && $i requests)) {
  157. $ch = curl_init();
  158. $options = $this->get_options($this->requests[$i]);
  159. curl_setopt_array($ch, $options);
  160. curl_multi_add_handle($queue, $ch);
  161. $key = (string) $ch;
  162. $this->requestMap[$key] = $i;
  163. $i++;
  164. }
  165. curl_multi_remove_handle($queue, $done['handle']);
  166. echo "done ";
  167. print_r($queue);
  168. print_r ($done);
  169. }
  170. // 这一步非常非常重要如果有一个完成后,要重新设置设置timeout的时间
  171. //这里很关键的一点,就是要保证第一次所有的线程里的请求最少有一个是有效的,否则就出现第一次所有的都没有效果,导致 $active=0,因此不执行下面的东西
  172. if ($active >0){
  173. curl_multi_select($queue, $this->timeout);
  174. }
  175. } while ($active);
  176. curl_multi_close($queue);
  177. return true;
  178. }
  179. public function execute($thread_size = null) {
  180. //判断thread_size的大小如果只有一个请求,就用单线程模式
  181. if (count($this->requests) == 1) {
  182. return $this->single_curl();
  183. } else {
  184. return $this->rolling_curl($thread_size);
  185. }
  186. }
  187. private function get_options($request) {
  188. $options = $this->__get('options');
  189. if (ini_get('safe_mode') == 'Off' || !ini_get('safe_mode')) {
  190. // $options[CURLOPT_FOLLOWLOCATION] = 1;
  191. // $options[CURLOPT_MAXREDIRS] = 5;
  192. }
  193. $headers = $this->__get('headers');
  194. if ($request->options) {
  195. $options = $request->options + $options;
  196. }
  197. $options[CURLOPT_URL] = $request->url;
  198. //下面分别对post选项与header选项进行设置
  199. if ($request->post_data){
  200. $options[CURLOPT_POST] = 1;
  201. $options[CURLOPT_POSTFIELDS] = $request->post_data;
  202. }
  203. if ($headers) {
  204. $options[CURLOPT_HEADER] = 0;
  205. $options[CURLOPT_HTTPHEADER] = $headers;
  206. }
  207. return $options;
  208. }
  209. public function __destruct() {
  210. unset($this->thread_size, $this->callback, $this->options, $this->headers, $this->requests);
  211. }
  212. }
  213. ?>
复制代码
  1. header("content-type:text/html; charset=utf-8");
  2. require("muti_curl_class.php");
  3. set_time_limit(0);
  4. $sucesesnum=0;
  5. $good_proxy=array();
  6. function request_callback($response, $info, $request) {
  7. global $sucesesnum,$good_proxy;
  8. // 下面的正则可以对返回的结果进行选择性显示
  9. /* if (preg_match("~(.*?)~i", $response, $out)) {
  10. $title = $out[1];
  11. }*/
  12. // echo '
    '.$response .'
    ';
  13. echo '
    ';
  14. //对响应也就是 $response 进行检测判断里面是否有设定的字符,如果有判断运用该代理成功
  15. if( $response !== false && substr_count($response, 'User-agent: Baiduspider') >=1 ) {
  16. // $result = true;
  17. echo "true
    ";
  18. // echo $request[options][10004];
  19. // print_r ($request->options);
  20. echo $request->options[CURLOPT_PROXY];
  21. $good_proxy[]=$request->options[CURLOPT_PROXY];
  22. }
  23. echo '
    the-->'. $sucesesnum.'// print_r ($request);
  24. //echo $request->url;
  25. $sucesesnum++;
  26. echo "
    ";
  27. }
  28. $params = array_merge($_GET, $_POST); //此处获得传递过来的代理ip的地址
  29. $result = $proxy_ip = trim($params['ip']);
  30. $timeout=intval(trim($params['timeout']));
  31. if($timeoutif($timeout>300){$timeout=300;}
  32. $thread_size=intval(trim($params['thread_size']));
  33. if($thread_sizeif($thread_size>300){$thread_size =300;}
  34. if($proxy_ip == '') {
  35. echo '请输入IP!!';
  36. return;
  37. }
  38. $replace_arr1 = array(' ', 'qq代理:', 'dn28.com', 'qqip', 'qq代理', 'qq代理ip', '代理ip:', 'ip:', '代理ip','"',"'",'\\','/',' ');
  39. $result = str_replace($replace_arr1, array(''), $result);
  40. $result = str_replace(",", "\n", $result);
  41. $resArr = explode("\n", $result);
  42. foreach($resArr as $k => $v) {
  43. $posProxy = getPos($v, '@');
  44. if($posProxy===false){
  45. if (!empty($v)){$proxyip_and_port = $v; }
  46. }else{
  47. $proxyip_and_port = substr($v, 0, $posProxy);
  48. }
  49. $newRes[] =trim($proxyip_and_port);
  50. }
  51. print_r($newRes);
  52. //die();
  53. $option_setting = array(
  54. CURLOPT_SSL_VERIFYPEER => 0,
  55. CURLOPT_RETURNTRANSFER => true,
  56. CURLOPT_CONNECTTIMEOUT => 5,
  57. CURLOPT_TIMEOUT => 30,
  58. CURLOPT_HEADER=>false,
  59. CURLOPT_PROXY=>'',//这个地方设置代理的位置
  60. );
  61. $url= 'http://www.baidu.com/robots.txt';
  62. $btime=time();
  63. $rc = new muti_curl("request_callback");
  64. $rc->timeout = $timeout;
  65. $rc->thread_size = $thread_size;
  66. foreach ($newRes as $v) {
  67. $option_setting[CURLOPT_PROXY]=$v;
  68. $request = new request_setting($url, $method = "GET", $post_data = null,$header= null, $option_setting);
  69. $rc->add($request);
  70. }
  71. $rc->execute();
  72. $etime=time();
  73. $usedtime=$etime-$btime;
  74. echo 'all'. $sucesesnum.'use'. $usedtime;
  75. echo '
    ';
  76. $good_proxy= array_unique($good_proxy);
  77. $str='';
  78. foreach ($good_proxy as $v){
  79. $str.="'".trim($v)."',";
  80. }
  81. $str= str_replace ( ' ' , '' ,$str );
  82. $str = preg_replace('/\s+/', ' ', $str);
  83. echo $str.'
    ';
  84. var_export ($good_proxy);
  85. //var_dump ($good_proxy);
  86. //**************************************************************************************************
  87. //*******************************只用了一个函数
  88. function parseProxyInfo ( $proxyStr ) {
  89. //$proxyStr = '202.115.207.25:80@HTTP;四川省成都市 四川师范大学';
  90. $posIp = getPos($proxyStr, ':');
  91. $ip = substr($proxyStr, 0, $posIp);
  92. $posPort = getPos($proxyStr, '@');
  93. $port = substr($proxyStr, $posIp+1, $posPort-$posIp-1);
  94. $posType = getPos($proxyStr, ';');
  95. $type = substr($proxyStr, $posPort+1, $posType-$posPort-1);
  96. $location = substr(strstr($proxyStr, ';'), 1);
  97. return array(
  98. 'ip' => $ip,
  99. 'port' => $port,
  100. 'type' => $type,
  101. 'location' => $location
  102. );
  103. }
  104. function getPos($haystack, $needle){
  105. return strpos($haystack, $needle);
  106. }
  107. function check_proxy_is_useful($model, $proxy_info_arr = array()) {
  108. global $params, $config;
  109. if($model == 'single') {
  110. $proxy_port = intval(trim($params['port']));
  111. $check_proxy_url = $config['verify_url'];
  112. $proxy_time_out = intval(trim($params['timeout']));
  113. $retry = intval(trim($params['retry']));
  114. $proxy_ip = trim($params['ip']);
  115. $proxy = new proxy( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
  116. //成功返回string success, 失败返回boolean false
  117. $result = $proxy -> check_proxy();
  118. //var_dump($result);
  119. $proxy_str_success = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP 代理验证成功!';
  120. $proxy_str_failed = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP 代理验证失败!';
  121. return $result !== false ? $proxy_str_success : $proxy_str_failed;
  122. } elseif ($model == 'collect') {
  123. $proxy_port = intval(trim($proxy_info_arr['port']));
  124. $check_proxy_url = $config['verify_url'];
  125. $proxy_time_out = intval(trim($params['timeout']));
  126. $retry = intval(trim($params['retry']));
  127. $proxy_ip = trim($proxy_info_arr['ip']);
  128. /*echo $proxy_ip.'
    ';
  129. echo $proxy_port.'
    ';
  130. echo $check_proxy_url.'
    ';
  131. echo $proxy_time_out.'
    ';
  132. echo $retry.'
    ';*/
  133. if(!isset($proxy)) {
  134. $proxy = new proxy( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
  135. }
  136. //成功返回string success, 失败返回boolean false
  137. $result = $proxy -> check_proxy();
  138. return $result;
  139. }
  140. }
  141. function get_single(){
  142. global $params, $config;
  143. $proxy_ip = trim($params['ip']);
  144. if($proxy_ip == '') {
  145. echo '请输入IP!!';
  146. return;
  147. }
  148. echo check_proxy_is_useful('single');
  149. }
  150. function get_proxy_by_collect(){
  151. global $params, $config;
  152. $params['url'] = trim($params['url']);
  153. if($params['url'] == '') {
  154. echo '请输入url!';
  155. return;
  156. }
  157. //$url = 'http://www.dn28.com/html/75/n-5175.html';
  158. $con = iconv('GBK', 'UTF-8', file_get_contents($params['url']));
  159. preg_match ('/(.*)
    /s', $con, $arr);
  160. $result = strip_tags ($arr[1], '
    ');
  161. $replace_arr1 = array(' ', 'qq代理:', 'dn28.com', 'qqip', 'qq代理', 'qq代理ip', '代理ip:', 'ip:', '代理ip');
  162. $result = str_replace($replace_arr1, array(''), $result);
  163. //print_r($arr);
  164. $resArr = explode('
    ', $result);
  165. //print_r($resArr);
  166. echo '

    代理开始批量验证中,整个过程将会花费您几分钟时间。

    ';
  167. unset($_SESSION['success_arr']);
  168. foreach($resArr as $k => $v) {
  169. $newRes[$k] = parseProxyInfo($v);
  170. //print_r($newRes[$k]);
  171. /*return;*/
  172. $result = check_proxy_is_useful('collect', $newRes[$k]);
  173. $proxy_str_success = ''.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].' 代理验证成功!   IP地址:'.$newRes[$k]['location'].'';
  174. $proxy_str_failed = ''.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].' 代理验证失败!   IP地址:'.$newRes[$k]['location'].'';
  175. if($result !== false ){
  176. echo $proxy_str_success;
  177. $_SESSION['success_arr'][] = $success_arr[] = $newRes[$k];
  178. } else {
  179. echo $proxy_str_failed;
  180. }
  181. echo '
    ';
  182. }
  183. if(isset($success_arr) && count($success_arr) > 0 ) {
  184. save_success_proxy($success_arr);
  185. echo '

    [保存验证成功的代理到本地电脑]   [我要看看历史数据]

    ';
  186. } else {
  187. echo '

    [我要看看历史数据]

    ';
  188. }
  189. //print_r($success_arr);
  190. }
  191. function get_proxy_by_rule(){
  192. global $params, $config;
  193. $result = $proxy_ip = trim($params['ip']);
  194. if($proxy_ip == '') {
  195. echo '请输入IP!!';
  196. return;
  197. }
  198. $replace_arr1 = array(' ', 'qq代理:', 'dn28.com', 'qqip', 'qq代理', 'qq代理ip', '代理ip:', 'ip:', '代理ip');
  199. $result = str_replace($replace_arr1, array(''), $result);
  200. $resArr = explode("\n", $result);
  201. //print_r($resArr);
  202. echo '

    代理开始批量验证中,整个过程将会花费您几分钟时间。

    ';
  203. unset($_SESSION['success_arr']);
  204. foreach($resArr as $k => $v) {
  205. $newRes[$k] = parseProxyInfo($v);
  206. //print_r($newRes[$k]);
  207. /*return;*/
  208. $result = check_proxy_is_useful('collect', $newRes[$k]);
  209. //var_dump($result);
  210. $proxy_str_success = ''.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].' 代理验证成功!   IP地址:'.$newRes[$k]['location'].'';
  211. $proxy_str_failed = ''.$newRes[$k]['ip'].':'.$newRes[$k]['port'].'@'.$newRes[$k]['type'].' 代理验证失败!   IP地址:'.$newRes[$k]['location'].'';
  212. if($result !== false ){
  213. echo $proxy_str_success;
  214. $_SESSION['success_arr'][] = $success_arr[] = $newRes[$k];
  215. } else {
  216. echo $proxy_str_failed;
  217. }
  218. echo '
    ';
  219. }
  220. if(isset($success_arr) && count($success_arr) > 0 ) {
  221. save_success_proxy($success_arr);
  222. echo '

    [保存到php格式文件]   [保存验证成功的代理到本地电脑]   [我要看看历史数据]

    ';
  223. } else {
  224. echo '

    [我要看看历史数据]

    ';
  225. }
  226. }
  227. function save_success_proxy($success_arr){
  228. global $config;
  229. date_default_timezone_set('PRC');
  230. $str = '';
  231. foreach($success_arr as $k => $v) {
  232. $str .= $v['ip'].':'.$v['port'].'@'.$v['type'].';'.$v['location']."\n";
  233. }
  234. $fp = fopen($config['root_path'].'/success_proxy/'.date('YmdHi').'.log', 'a+');
  235. fwrite($fp, $str);
  236. fclose($fp);
  237. unset($str);
  238. }
  239. ?>
复制代码


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Expliquez les jetons Web JSON (JWT) et leur cas d'utilisation dans les API PHP. Apr 05, 2025 am 12:04 AM

JWT est une norme ouverte basée sur JSON, utilisée pour transmettre en toute sécurité des informations entre les parties, principalement pour l'authentification de l'identité et l'échange d'informations. 1. JWT se compose de trois parties: en-tête, charge utile et signature. 2. Le principe de travail de JWT comprend trois étapes: la génération de JWT, la vérification de la charge utile JWT et l'analyse. 3. Lorsque vous utilisez JWT pour l'authentification en PHP, JWT peut être généré et vérifié, et les informations sur le rôle et l'autorisation des utilisateurs peuvent être incluses dans l'utilisation avancée. 4. Les erreurs courantes incluent une défaillance de vérification de signature, l'expiration des jetons et la charge utile surdimensionnée. Les compétences de débogage incluent l'utilisation des outils de débogage et de l'exploitation forestière. 5. L'optimisation des performances et les meilleures pratiques incluent l'utilisation des algorithmes de signature appropriés, la définition des périodes de validité raisonnablement,

Expliquez le concept de liaison statique tardive en PHP. Expliquez le concept de liaison statique tardive en PHP. Mar 21, 2025 pm 01:33 PM

L'article traite de la liaison statique tardive (LSB) dans PHP, introduite dans PHP 5.3, permettant une résolution d'exécution de la méthode statique nécessite un héritage plus flexible. Problème main: LSB vs polymorphisme traditionnel; Applications pratiques de LSB et perfo potentiel

Caractéristiques de sécurité du cadre: protection contre les vulnérabilités. Caractéristiques de sécurité du cadre: protection contre les vulnérabilités. Mar 28, 2025 pm 05:11 PM

L'article traite des fonctionnalités de sécurité essentielles dans les cadres pour se protéger contre les vulnérabilités, notamment la validation des entrées, l'authentification et les mises à jour régulières.

Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Comment envoyer une demande post contenant des données JSON à l'aide de la bibliothèque Curl de PHP? Apr 01, 2025 pm 03:12 PM

Envoyant des données JSON à l'aide de la bibliothèque Curl de PHP dans le développement de PHP, il est souvent nécessaire d'interagir avec les API externes. L'une des façons courantes consiste à utiliser la bibliothèque Curl pour envoyer le post� ...

Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Mar 28, 2025 pm 05:12 PM

L'article examine l'ajout de fonctionnalités personnalisées aux cadres, en se concentrant sur la compréhension de l'architecture, l'identification des points d'extension et les meilleures pratiques pour l'intégration et le débogage.

Décrivez les principes solides et comment ils s'appliquent au développement de PHP. Décrivez les principes solides et comment ils s'appliquent au développement de PHP. Apr 03, 2025 am 12:04 AM

L'application du principe solide dans le développement de PHP comprend: 1. Principe de responsabilité unique (SRP): Chaque classe n'est responsable d'une seule fonction. 2. Principe ouvert et ferme (OCP): les changements sont réalisés par extension plutôt que par modification. 3. Principe de substitution de Lisch (LSP): les sous-classes peuvent remplacer les classes de base sans affecter la précision du programme. 4. Principe d'isolement d'interface (ISP): utilisez des interfaces à grain fin pour éviter les dépendances et les méthodes inutilisées. 5. Principe d'inversion de dépendance (DIP): les modules élevés et de bas niveau reposent sur l'abstraction et sont mis en œuvre par injection de dépendance.

Comment fonctionne le détournement de session et comment pouvez-vous l'atténuer en PHP? Comment fonctionne le détournement de session et comment pouvez-vous l'atténuer en PHP? Apr 06, 2025 am 12:02 AM

Le détournement de la session peut être réalisé via les étapes suivantes: 1. Obtenez l'ID de session, 2. Utilisez l'ID de session, 3. Gardez la session active. Les méthodes pour empêcher le détournement de la session en PHP incluent: 1. Utilisez la fonction Session_RegeReate_id () pour régénérer l'ID de session, 2. Stocker les données de session via la base de données, 3. Assurez-vous que toutes les données de session sont transmises via HTTPS.

See all articles