标签归档:php

PHP并行cURL中socks代理问题

这是一篇被坑记录。关键字: CURLOPT_PROXY, CURLPROXY_SOCKS5, curl, curl_multi_init, curl_multi_add_handle, curl_multi_exec, curl_getinfo, socks5.

我的友链状态是通过cron任务定时调用php脚本来检查的,并且这个脚本通过curl走socks5代理出去请求网站和对应的logo。

本来这个脚本是遍历json中的友链一个个去请求然后设置状态的,逻辑上没有任何问题,也可以顺利完成检测,问题是这样的检测时间太长了,如果我手动请求检测脚本的地址那么一定会执行超时,而且我会看不见结果。于是我想把这个脚本里的请求改成并行的,一次性请求所有网站。然后问题来了,按照php手册上 curl_multi系列的函数改好了脚本之后无论怎么运行怎么修改一定会执行失败。无论怎么修改,curl multi组一定会超时,所有请求都会失败,浪费了我六七个小时研究这个问题。

 

直到我偶然间看到了这个页面上的这段话

10.1 SOCKS proxy connections are done blocking

Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very bad when used with the multi interface.

我记得曾经我就尝试过把这个脚本改成并行请求,但也是因为无论如何都会请求失败后来直接放弃了。这个影响那么大的bug几年过去了依然没有修好,不愧是世界上最好的语言。

也就是说现在php的并行cURL不能设置socsk代理,否则一定会阻塞住然后请求失败,要解决这个问题只能改用http代理。

PHP传入参数

今天我才知道php脚本用php直接执行的时候是可以传入参数的,这样本地共享session就不需要建个服务器再访问啊什么的。
这里放个例子
文件a.php

<?php
    $args = getopt('a:b:');
    print_r($args);
?>

执行 `php a.php -a miao -b 123`

结果

Array
(
    [a] => miao
    [b] => 123
)

[PHP]禁止json_encode显式转换为UTF8编码

我今天发现弹幕播放器载入的弹幕虽然不多,但是传回的弹幕json却很大,于是我想起了一个鬼故事[json_encode对[非正常字符]的显式utf8转换],所以很多弹幕数据会被转换成字符形式的utf8码『\uxxxx』,虽然英文字符和中文字符实际上占用的大小不一样,不过把文字显式转换成utf8码仍然是额外消耗空间的,json完全可以保留原本的文字进行json格式化。

那么现在问题来了,会画画的妹纸好还是会唱歌的妹纸好呢
那么现在问题来了,json是否可以直接取消utf8转换呢?如果可以那真是极好,要是不可以的话还得在转换以后正则替换掉所有utf8码。

还好json_encode的第二个设置参数可以设置

 json_encode(数组,JSON_UNESCAPED_UNICODE);

这样就可以取消utf8显式转换了,某视频的弹幕返回的json也从90+K变成了50+K。

[PHP]清理js文件

花了点时间好好做了个可以清理js文件的php脚本,php确实是个蛋疼的东西,老是出点奇怪的特性。

这个脚本的功能是去掉js文件里的无用部分,输出一个清洁的js文件(当然我不保证这个输出的文件绝对没问题,至少把我的COL放进去输出的文件没问题)

原理:
由于涉及到清理注释,又不能把引号误删,而且 `”` `’` `//` `/*`这四个关键符号是同样优先级的,所以谁先出现,谁的优先级就会高(也就是其他符号都会进入这个符号的作用域里)

比如`”` 先出现了,后面的`’` `//` `/*`都会被包括进这个字符串里,同样如果`/*`先出现了后面的内容都会变成注释,除非碰到`*/` 。

所以我用了个循环来根据先出现的符号进行相应操作。碰到引号就把字符串整个提出来放个锚,即可保持字符串内容,然后就不用再担心字符串的问题了。

继续阅读[PHP]清理js文件

PHP获取文件大小

今天码PHP的时候碰到一个很蛋疼的问题,我在做文件床路由模块的时候测试用php输出文件下载,但是很大的文件永远下载不完整,浏览器只会下几百M然后就结束了。

于是我开始从文件输出部分开始一步步往回推,到最后发现原来是服务器告诉浏览器这个文件只有这么大,于是浏览器接收了这么多字节后就关闭连接了。

接着我就开始filesize各种大小的文件,发现大于4G的文件都会出现这样的情况,于是我就去php.net逛了一下,只见这血淋淋的一幕

NoteBecause PHP’s integer type is signed and many platforms use 32bit integers, some filesystem functions may return unexpected results for files which are larger than 2GB.

注意:因为PHP的整数类型是有符号整数并且很多平台还他喵的在用32位整数,一些文件系统相关的函数作用在大于2GB文件时可能返回感天动地的结果。

我只想说————————————坑爹呢这是!你都那么多代了这个函数还不升级一下简直有病吧! 继续阅读PHP获取文件大小

让网站全球化

让网站全球化可以吸引更多的用户和访问,全球化最重要的就是让各地的人都看得懂你的网站上写了些啥。在我玩联机OSU的时候甚至很多外国人让我们不要说日语。。。。[这是傲娇卖萌?]
那么接下来进入正题,刚刚中午趴在床上很无奈的想到了这个问题。[为啥无奈呢?因为又不想起床,不起床又没有wifi信号。。。。],实际上也是我为iTi想的问题,有可能我已经想的太远了,但是有些想法还是很好的。

特别加注
很多围观者还没仔细看完就私下告诉我直译不通什么的。。。
这种方法只是用于翻译小区块的文字的,比如“登录”,“取消”之类的,不是用来翻译大片文章的,大篇文章的翻译工作为了用户体验必须单独成库或者成表。
首先说一下简单逻辑:
>定义翻译表
>传入原文
>检测翻译表
>返回对应值

大体就是这样了。
继续阅读让网站全球化

PHP Global

本文内容最终以PHP: 变量范围 – Manual中的Global部分为准。

博主很粗心的研究了一下文档就来写这篇文章了,只是做个笔记,并且没有做测试,所有内容都是我猜的[不怕被我误导的话就看下去吧],有错误请指出,没什么问题的话也提醒我一下,我来给文章mark下可信。
首先说一下我总结出来的Global使用规则先。
1.在函数里使用在函数外定义的变量在变量前加上至少一次Global来访问。
2.要让函数里的变量可以被外部访问,就要在函数里定义的变量之前加上Global,然后可以在外部直接使用,如果在其它函数里使用的话,参考1。

接下来是正文,如果上面的规则没看懂的话,下面会给出一些例子来帮助理解。
继续阅读PHP Global

server-sent 服务器主动发送事件

以前的HTML版本中,要获取实时数据,必须要不断向服务器发出请求来查询有没有新内容,这样不管从建立连接还是等待时间来说都是要多苦逼就有多苦逼啊(微观来说),[最近死在学校里实在没事做就去逛了逛w3,中文的w3school更新比英文版慢了不知多少啊]然后我发现了w3的html专版里多出了一个HTML5 服务器发送事件这东西。
看了一下他的介绍大概知道她是干什么用的了,简单地说就是用javascript建立一个长连接到一个网页脚本,然后脚本就可以按需向浏览器页面主动发送数据。

下面来解释一下工作方式

//这是我整合了w3里的示例代码,添加详细注释来助解
if (typeof(EventSource) !== "undefined") {//检查是否支持服务器推送
	var a = new EventSource("脚本.php");//建立和"脚本.php"的连接
	a.onmessage=function(event) {//接收到消息的事件
		/*这里的event.data存储了从服务器传回来的数据*/
        /*比如alert(event.data)来提示返回的数据*/
	};
    
    a.onopen=function(event){//打开连接时的事件
    /*用event.readyState可以获取此时的状态号*/
        /*建立好连接的时候干些什么*/
    };
    
    a.onerror=function(event){//发生错误时的事件
    /*用event.readyState可以获取此时的状态号*/
        /*发生错误的时候干些什么*/
    };
} else {//不支持推送的话
	alert("您老的浏览器不支持服务器推送");
    
    a.close();//用close()方法可以关闭连接
    a=null;//把a对象清空,让它的空间自动被回收
}

判断访问者是否是搜索引擎

有的时候我们需要针对搜索引擎抓取做一些特殊的回应、所以要用到判断是否为搜索引擎的方法,我在网上找了几种来做个笔记,就先不验证效果了。

第一种
来源:php判断是否搜索引擎 – php

function strexists($haystack, $needle) {
       return !(strpos($haystack, $needle) === FALSE);
} 
/*
*检验搜索
*/
function getrobot() {   
    if(!defined('IS_ROBOT')) {   
        $kw_spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla';   
        $kw_browsers = 'MSIE|Netscape|Opera|Konqueror|Mozilla';   
        if(!strexists($_SERVER['HTTP_USER_AGENT'], 'http://') && preg_match("/($kw_browsers)/i", $_SERVER['HTTP_USER_AGENT'])) {   
            define('IS_ROBOT', FALSE);   
        } elseif(preg_match("/($kw_spiders)/i", $_SERVER['HTTP_USER_AGENT'])) {   
            define('IS_ROBOT', TRUE);   
        } else {   
            define('IS_ROBOT', FALSE);   
        }   
    }   
    return IS_ROBOT;   
}

看代码这一种方法是判断来访者是不是某一种浏览器,如果是的话就判断为用户,不是的话就判断为蜘蛛。 继续阅读判断访问者是否是搜索引擎

memcache用法笔记

PS:虽然本文是我写的但是我还没有经过实验。。。如果发现了错误请留言让我修正
PS:[ ]中的都为可有可无的内容
ps:第一次给文章加这么多样式。。感慨万千吖

Memcache是一个内存存储方案[多简洁的描述啊。。]

在PHP官方有比较全面的说明文档

http://www.php.net/manual/zh/book.memcache.php【中文】

这里就来简单写一下他的数据操作部分的用法

创建一个Mencache对象

$memobj=new Memcache;
//使用函数形式的时候不需要创建这个对象

然后就可以以对象的形式对他进行操作

继续阅读memcache用法笔记

选择性使用网站背景图片

最近的一篇文章主题【3】的背景坎坷里写到了背景图片的background-size: cover这个css对移动设备并不怎么友好,无法达到标准的显示效果,于是我一直在想办法使用img标签来填补这个bug,不过今天我又不想做了,所以找了个理由。[接下来就是理由]

如可以正常浏览本站的童鞋们所见,我的div背景大部分都是半透明的,寒假里了解openGL的时候感觉透明处理真心很费神啊[对计算机来说],所以我决定让移动设备就干脆不显示背景图了。这样不仅省去好多渲染步骤,看起来还清爽,顺便间接的帮我解决了移动设备上背景图的撑满问题。
继续阅读选择性使用网站背景图片

ajax那啥的通用框架

ajax虾米的最有爱了,用起来也很方便。。【第一次写长文,出错请留言来让我改正】

var xmlhttp; //创建一个Request对象先
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("POST或者GET","请求的脚本文件",true或false【不加引号,true是异步,false是同步】);          //异步通俗的说就是请求时浏览器接着干其他事,同步就是浏览器要等服务器处理完了才接着做其他事
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200) //当海枯石烂的时候
{
//这里就可以做ajax接收后行为的事了,然后xmlhttp.responseText是从服务器扔回来的数据。
}
}
xmlhttp.send("这里是发送出去的数据");

继续阅读ajax那啥的通用框架