月度归档 2016年5月16日

通过清心醉

php进行POST请求INPUT过多导致被截取的解决方法

今天修改微影院的开发,其中涉及座位最为麻烦,布局规划还需要有一个走道,如此一来,数据量是相当的庞大。

比如说,有20排,每排50个座位,那么就会出现1000个INPUT,而且还要有ID进行座位的详细捆绑

这么一来,就会有多个INPUT的数组。

一开始以为是请求的数据过大,修改了post_max_size = 32M,可是请求数据的时候,一样被截取。

作者请求的数组有3个,每个数组内有1000个数值,总累计INPUT的数量超过了3000个

GOOGLE搜索了一下,发现PHP5.3开始有个新的控制方法:max_input_vars

没错了,max_input_vars默认控制的数值是在1000内,如果超过的1000个就会被截取。

所以,修改max_input_vars就可以满足POST的数据请求!

通过清心醉

MYSQL优化之LIMIT

我们知道,一套应用程序的运行,除了程序代码的质量,硬盘磁盘的I/O,还有一个就是SQL的高并发及查询了;

代码的质量在于程序员们如何去优化,磁盘I/O可以使用负载均衡,至于SQL当然也是可以使用负载均衡,然后进行数据的交互同步即可。当然了,前提是,做一个完善的负载均衡,站在作者的立场上来看,弄个光钎转线+服务器的一次性配置,没有个10万下不来,如果是精益求精的服务需求,单是服务器的配置就得200万+,所以,土豪老板和开发者就免看了!

在此对蛋蛋工作室的小张说声对不起,由于最近项目时间太紧,没去给他优化SQL的检索优化。

本文暂不提供MYSQL完整的负载均衡部署方式!

SQL,开发人员都知道是用来存储数据的,居然是存储数据,就会占用文件资源,我见过最大的数据库是几十GB的,当然数据量是近亿行;

我们来假设一下,一个10GB的数据库表数据,从中读取数据的时候,磁盘的I/O要占用多少?哪怕只是在UNIX里打开,也是吓人的,然后再进行SQL的查询。可以想象成10GB的数据是足球场,在座的每一位观众是一个数据,要想在足球场中找出某个人,是多么的难?

因此,有了索引、主键;好比我给每个观众捆绑一个座位号(比如ID主键),这时候,我要知道哪个用户在哪,直接通过ID就能马上获取了对应的位置,要找就好找了,因为我有了详细的座位号了!

跑题了,回到主题,LIMIT

一个高效的SQL语句,是脱离不开LIMIT的,比如用户的登陆

“SELECT user,password FROM `user` WHERE `user`=’$user’ AND `password`=’$password’ LIMIT 1;

这语句是不是感觉有点多余了? 用户名和密码都验证了,干嘛还判断?

正确的答案是,必须要!

假设阿里的淘宝用户是几个亿,如果都在一个表内,不进行LIMIT 1,SQL会全盘扫描,哪怕后面的数据没有重复的,都会全部扫下去,然后把对应的数据提取出来,如果一个1G的用户表,需要耗时是多少?

当然,如果有足够的服务器,可以把用户名+ID写入MEMCHACHE等缓存系统,在通过用户名获取对应的ID

然后”SELECT user,password FROM `user` WHERE `user`=’$user’ AND `password`=’$password’ WHERE `id`= x;的方式来进行,ID设置个主键,0秒内查询出基本不是问题。这也是负载均衡常用的做法;

就这一个简单的用户登陆查询,我想你看到这的时候,已经理解深刻了吧?

特别商城网站,为什么要有翻页?翻页原理有什么好?

1:优化用户视觉体验,不会被那么多的产品混淆;

2:数据的提取;

作者以前也写过一个留言版,是支持翻页的,当然,就是需要LIMIT来进行控制了。

执行全盘扫描的时候,先LIMIT 1 100;二次执行的时候LIMIT 101 200;以此类推,避免了数据量千万级甚至亿级的全盘扫描导致服务器宏机!

 

 

通过清心醉

php-mysql主从表关联查询获取数据重复的解决方法

首先我们这有两张表,一个主表,一个从表

主表:TheFilm_Name包含以下关键字段

id =>int(11)唯一自增加;

name => varchar(32)节目名称;

access_token => varchar(32)多个管理员的唯一内部令牌

从表:TheFilm_Data包含以下关键字段

id=>int(11) 唯一自增ID,主要用于记录行数和做主键;

status=>int(4) 节目状态,0=未启用,1=启用中,2=播放完毕

access_token => varchar(32)多个管理员的唯一内部令牌

name_id => int(11) 对应的节目名称ID;

好了言归正传,如果我们要提取TheFilm_Name对应的节目详细数据status=1的,那么我们可以执行语句:

SELECT * FROM `TheFilm_Name` t1 LEFT JOIN `TheFilm_Data` t2
ON(t1.id=t2.name_id AND t1.access_token=t2.access_token) WHERE t2.status=’1′ AND t2.access_token=’admin_token’;

如此一执行,就会把TheFilm_Data内的所有status=1并且对应access_token的数据提取出来了;

但又有那么一个问题:

因为节目就那么几个,详细的可能涉及多个,比如一个节目(西游记),可能有多个数据(比如根据不同的时候写入到了TheFilm_Data),那么就会出现重复的数据;

一个简单的关联查询解决重复的问题:在于一句:GROUP BY t1.id;

SELECT t1.* FROM `TheFilm_Name` t1 LEFT JOIN `TheFilm_Data` t2
ON(t1.id=t2.name_id AND t1.access_token=t2.access_token) WHERE t2.status=’1′ AND t1.access_token=’admin_token’ GROUP BY t1.id; ORDER BY t1.id DESC;

在这特别注意,因为是关联查询,而且两个表内都有ID值,所以加上t1.*表示提取TheFilm_Name的全部

通过清心醉

NGINX反向请求APACHE的伪静态出现404错误

刚在配置盼盈信息港的时候,出现了404,这页面不陌生。

首先看看NGINX的配置吧:

server {
listen 80;
server_name ipanying.cn *.ipanying.cn;
location / {
root /var/webs/ipanying/public_html/;
index index.php index.html index.htm;

location ~ .*\.(js|css)$ {
access_log off;
expires 1d;
}

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
access_log off;
expires 3d;
}
location ~ .*\.(php?|cgi|pl|py)$ {
proxy_pass http://127.0.0.1:9999;
proxy_set_header Host $host;
}
}
}

 

很清楚的看到location ~ .*\.(php?|cgi|pl|py)$反向请求给APACHE的9999端口

因为APACHE端口默认是80,而我修改成127.0.0.1:9999

自认没错啊,因为9999端口只允许内网访问(即外网无法非法获取,甚至我可以在NGINX进行更多的负载均衡的反向请求);

在根目录内放个文件打印phpinfo()却没问题;这让我联想到反向请求的根本,问题自然就清晰了!

location ~ .*\.(php?|cgi|pl|py)$居然都把请求发向转发给APACHE了,而伪静态是.html做结尾,自然而然该页面是由NGINX进行动作!可是NGINX对伪静态之后的.html文件进行数据解析,却是不存在的。

所以,以下的这段

location ~ .*\.(php?|cgi|pl|py)$ {
proxy_pass http://127.0.0.1:9999;
proxy_set_header Host $host;
}

明显就有问题。如果是针对DEDE这种国产高I/O开销的纯静态页面是可以进行的,因为静态.html文件是实实在在存在的。所以针对动态伪静态,应该修改为:

#location ~ .*\.(php?|cgi|pl|py)$ {
proxy_pass http://127.0.0.1:9999;
proxy_set_header Host $host;
#}

没错,注释掉就解决问题!

如果你有更多的服务器配置问题,欢迎咨询,LANMP任意组合任意版本!

 

 

通过清心醉

PHP-MYSQL什么情况下应该用INT?

当然,该说明不只是针对PHP,NET和JSP如果对MYSQL进行操作一样也是可以的,而且对于ACCESS等其他数据库原理相同。(也就是说,只要你懂任意一门程序开发语言+数据库语言,都是可以在最短的时间内进行其他语言+数据库的学习的,别不自信,作者自学C++基础一个月不足,就拿下了PHP面向对象的精通,学不好的人,只能怪程序不是你的爱好,放弃吧!)

数据库中,我们常使用到INT,VARCHAR

其中INT基本都主要用于主键、KEY、自增ID记录行等,当然,VARCHAR就是对字符的了。

直接给段代码吧,看不懂的好好学学你的MYSQL功底!

SELECT * FROM `ipanying_cn_user` WHERE `user_id` = '19185' AND `status` = '1' AND `re_time`+`lg_time` >'1462969356';
字段对应值为:
user_id=>int(11);
re_time=>int(11);
lg_time=>int(11);
简单来说,就是表内对应用户并且状态=1并且注册时间+现在时间>指定日期。作者是用来进行升级用户等级!
附提供出来!
通过清心醉

多级路由器网络连接配置

前言:公司使用了一台路由器+交换机,由于大家都是使用无线网络连接路由,导致部分有下载的时候连接路由连不上,更别说连外网了。

我们都知道无线网络也是有频率的,当到达了一定量的负荷程度,无线网是很难被连接的!

以下为方法:2台路由器:

1台路由器:IP:192.168.0.1

分发路由器:IP:192.168.2.1

首先设置192.168.0.1的路由器的WLAN等网络配置,保证其能正常联网

然后分条线到交换机(当然也是可以直接连线192.168.2.1的路由器)到路由器

注:192.168.2.1的原始IP也可能为192.168.0.1/192.168.1.1

确保两台路由之间的IP是不相同的,如果中途经过了多个路由/交换机,请使用尾数为:2.1/3.1/4.1/来进行区分

原理:

路由器1(192.168.0.1)直接通外网,内网会有192.168.0.2-192.168.0.254的可用IP段

路由器2(192.168.2.1)直接连接路由器1,或者路由器192.168.0.2-192.168.0.254可用的随机分配IP

在转化成路由器2内的内联IP(192.168.2.2-192.168.2.254)给予路由器2的用户使用

 

 

通过清心醉

php获取不同时间段的数据集

最近在做微影院的PHP开发,影院嘛,自然一个节目要在多个时间周期内使用。

假设有一部电影,安排的播放时间为:

2016-05-08 10:00:00 – 2016-05-08 11:45:00

2016-05-09 10:00:00 – 2016-05-09 11:45:00

2016-05-10 10:00:00 – 2016-05-10 11:45:00

2016-05-11 10:00:00 – 2016-05-11 11:45:00

2016-05-12 10:00:00 – 2016-05-12 11:45:00

然后我要显示3个大项目,一个为今天,二为明天,三为之后

如果今天/明天不存在,直接显示之后的全部

附带上个方法:

/**
* 根据节目信息进行时间序列化整理
* @param unknown $changci
* @return string|Ambigous <multitype:, multitype:unknown , multitype:unknown number >
*/
private function ChangCiData($changci){
if (empty($changci)){
return false;
}
$data=array(); #-对时间进行一个关联
date_default_timezone_set(‘Asia/Shanghai’); #-定义时区
for($i=0;$i<3;$i++){
$t = $i+1; #-日期默认+1
$time = mktime(0,0,0,date(“m”),date(“d”)+$t,date(“Y”)); #-获取时间,默认=第二天
for($o=0;$o<count($changci);$o++){ #-循环节目信息
if($i==2){ #-如果为第三次的关联
if($changci[$o][‘kaishi_time’]>($time-86000)){
#-开始时间全部就要求大于当前的
#-不过还有可能是有些小于第三天但又大于第二天的 所以条件修改为>第三天的时间-86000即大于2天后的
$data[$i][]=array(
‘time’ => $time, #-获取时间显示
‘yingpian’ => $changci[$o] #-获取详细信息
);
echo date(“Y-m-d”,$changci[$o][‘kaishi_time’]).”=jiemuid=”.$changci[$o][‘id’].”<br>”;
}
} else if($i==1){
if($changci[$o][‘kaishi_time’]<$time && $changci[$o][‘kaishi_time’]>($time-86000)){
#-如果开场的时间小于第二天的0点又大于前一天的
$data[$i][]=array(
‘time’ => $time, #-获取时间显示
‘yingpian’ => $changci[$o] #-获取详细信息
);
echo date(“Y-m-d”,$changci[$o][‘kaishi_time’]).”=jiemuid=”.$changci[$o][‘id’].”<br>”;
}
} else {
if($changci[$o][‘kaishi_time’]<$time){
#-如果开场的时间小于第二天的0点
$data[$i][]=array(
‘time’ => $time, #-获取时间显示
‘yingpian’ => $changci[$o] #-获取详细信息
);
echo date(“Y-m-d”,$changci[$o][‘kaishi_time’]).”=jiemuid=”.$changci[$o][‘id’].”<br>”;
}
}
}
}
return $data;
}

通过清心醉

javascript-select调用onchange方法错误

在这特别说下,能不用框架就别用框架,否则出现的问题会让你头痛的要命

首先来个JS代码,通用吧,然后在来罗列多种onchange不执行的问题

<script>
function ipanying(){
alert(“清心醉,网站开发建设运维SEO专业全栈开发工程师;”);
}
</script>

/**********************************************/

场景一:

<form>
<select name=”ipanying” id=”ipanying” onchange=”ipanying();”>
<option value=”0″>显示</option>
<option value=”1″>继续显示</option>
</select>
</form>

最终结果:无法执行,因为name和onchange调用的方法重名

/**********************************************/

场景二:

<select name=”ipanying” id=”ipanying” onchange=”ipanying();”>
<option value=”0″>显示</option>
<option value=”1″>继续显示</option>
</select>
最终结果:因为去除了form标签,所以是可以正常的执行!

/**********************************************/

场景三:

<form>
<select name=”ipanying1″ id=”ipanying” onchange=”ipanying();”>
<option value=”0″>显示</option>
<option value=”1″>继续显示</option>
</select>
</form>

最终结果:因为NAME值和onchange值不同,所以可以执行

/**********************************************/

经过多次的测试,select在form里对name和onchange有很高的要求判断

如果不是form表单则无任何影响