php is_writeable函数bug问题

其中bug存在两个方面,
1、在windowns中,当文件只有只读属性时,is_writeable()函数才返回false,当返回true时,该文件不一定是可写的。
如果是目录,在目录中新建文件并通过打开文件来判断;
如果是文件,可以通过打开文件(fopen),来测试文件是否可写。
2、在Unix中,当php配置文件中开启safe_mode时(safe_mode=on),is_writeable()同样不可用。
读取配置文件是否safe_mode是否开启。

/**
 * Tests for file writability
 *
 * is_writable() returns TRUE on Windows servers when you really can't write to
 * the file, based on the read-only attribute.  is_writable() is also unreliable
 * on Unix servers if safe_mode is on.
 *
 * @access	private
 * @return	void
 */
if ( ! function_exists('is_really_writable'))
{
	function is_really_writable($file)
	{
		// If we're on a Unix server with safe_mode off we call is_writable
		if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
		{
			return is_writable($file);
		}
 
		// For windows servers and safe_mode "on" installations we'll actually
		// write a file then read it.  Bah...
		if (is_dir($file))
		{
			$file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
 
			if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
			{
				return FALSE;
			}
 
			fclose($fp);
			@chmod($file, DIR_WRITE_MODE);
			@unlink($file);
			return TRUE;
		}
		elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
		{
			return FALSE;
		}
 
		fclose($fp);
		return TRUE;
	}
}

PHP判断上传图片的类型

PHP判断上传图片的类型
用getimagesize来判断上传图片的类型比$_FILES函数的type更可靠
同一个文件,使用不同的浏览器php返回的type类型是不一样的,由浏览器提供type类型的话,
就有可能被黑客利用向服务器提交一个伪装撑图片后缀的可执行文件。


如果通过getimagesize()函数返回的是这样的一个数组  其中索引为2的表示类型
1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte 
order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = 
JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
<pre>
Array
(
    [0] => 331
    [1] => 234
    [2] => 3
    [3] => width="331" height="234"
    [bits] => 8
    [mime] => image/png
)

nginx实现负载均衡

nginx实现负载均衡 几台服务器都可以用服务器镜像就可以了 这样就可以保持一致了

在http段加入以下代码: ps:默认 权重是平均分配的

upstream servers.mydomain.com { 
    server 192.168.2.3:80; 
    server 192.168.2.4:80; 
    server 192.168.2.5:80;
}

当然嘛,这servers.mydomain.com随便取的。

那么PA的server配置如下:
在http段加入以下代码:

server{ 
    listen 80; 
    server_name www.mydomain.com; 
    location / { 
        proxy_pass http://servers.mydomain.com; 
        proxy_set_header Host $host; 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 
}  

那么P1、P2、P3的配置如下:

server{ 
    listen 80; 
    server_name www.mydomain.com; 
    index index.html; 
    root /data/htdocs/www; 
}

PHP替代session的方法

PHP替代session的方法

服务器集群的时候 会发现session的问题

所以打算用替代session的方法
1 cookie代替session
2 如果有账号登录 就用账号作为唯一标识 进行记录 如果没有就只能采取第二种方法
3 用swoole 进行长连接 因为每个用户每次连接服务器 都会生成个fid 这个fid就是代表用户的标识 进行记录
4 app 可以用mac地址

PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法

PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法

1 最简单的方法就是用redis锁解决高并发的问题 再加上轮循环请求能请求到位置 (能提高用户体验性)

具体实现看http://newmiracle.cn/?p=488

比方说100个人同时抢红包
有1个人已经获取到锁码 那么还有99个人就会 进不去 提示 网络繁忙什么 请稍后再试试

2 就是用消息队列的方式 不过必须要用长连接 每次抢的人都进入队列 然后 后台会不断的提取 然后处理 并且返回对应的用户(fid)

swoole写个定时器 每秒运行一下

可以参考http://newmiracle.cn/?p=227

PHP中奖概率写法

PHP中奖概率写法

<?php
header("Content-type: text/html; charset=utf-8");
/*
 * 经典的概率算法,
 * $proArr是一个预先设置的数组,
 * 假设数组为:array(100,200,300,400),
 * 开始是从1,1000 这个概率范围内筛选第一个数是否在他的出现概率范围之内,
 * 如果不在,则将概率空间,也就是k的值减去刚刚的那个数字的概率空间,
 * 在本例当中就是减去100,也就是说第二个数是在1,900这个范围内筛选的。
 * 这样 筛选到最终,总会有一个数满足要求。
 * 就相当于去一个箱子里摸东西,
 * 第一个不是,第二个不是,第三个还不是,那最后一个一定是。
 * 这个算法简单,而且效率非常 高,
 * 关键是这个算法已在我们以前的项目中有应用,尤其是大数据量的项目中效率非常棒。
 */
function get_rand($proArr) {
    $result = '';
    //概率数组的总概率精度
    $proSum = array_sum($proArr);
    //概率数组循环
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);
        if ($randNum <= $proCur) {
            $result = $key;
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset ($proArr);
    return $result;
}


/*
 * 奖项数组
 * 是一个二维数组,记录了所有本次抽奖的奖项信息,
 * 其中id表示中奖等级,prize表示奖品,v表示中奖概率。
 * 注意其中的v必须为整数,你可以将对应的 奖项的v设置成0,即意味着该奖项抽中的几率是0,
 * 数组中v的总和(基数),基数越大越能体现概率的准确性。
 * 本例中v的总和为100,那么平板电脑对应的 中奖概率就是1%,
 * 如果v的总和是10000,那中奖概率就是万分之一了。
 *
 */
$prize_arr = array(
    '0' => array('id'=>1,'prize'=>'平板电脑','v'=>1),
    '1' => array('id'=>2,'prize'=>'数码相机','v'=>2),
    '2' => array('id'=>3,'prize'=>'音箱设备','v'=>3),
    '3' => array('id'=>4,'prize'=>'4G优盘','v'=>4),
    '4' => array('id'=>5,'prize'=>'10Q币','v'=>10),
    '5' => array('id'=>6,'prize'=>'下次没准就能中哦','v'=>80),
);

/*
 * 每次前端页面的请求,PHP循环奖项设置数组,
 * 通过概率计算函数get_rand获取抽中的奖项id。
 */
foreach ($prize_arr as $key => $val) {
    $arr[$val['id']] = $val['v'];
}
$rid = get_rand($arr); //根据概率获取奖项id    


$res = $prize_arr[$rid-1]; //中奖项      这种写法要根据实际情况写 
print_r($res);
?>

mysql left join和union结合的用法

left join和union结合的用法
子查询union 然后加个括号设置个别名 (union自动去除 重复的 )

select o.nickName,o.sex,o.province,o.city,from_unixtime(m.time,'%Y-%m-%d %H:%i:%s') as starttime,from_unixtime(z.time,'%Y-%m-%d %H:%i:%s') as endtime,ROUND((z.time-m.time)/60) as haoshifenzhong,from_unixtime(z1.time,'%Y-%m-%d') as choujiangtime from (select openid,time from xintjiashen_zhongjiang2   union select openid,time from xintjiashen_meizhong2) as z left join xintjiashen_my as m on z.openid=m.openid left join xintjiashen_zhongjiang1 as z1 on m.openid=z1.openid left join xintjiashen_oauthinfo as o on m.openid=o.wechatId where z1.prize_id !=8

phpexcel无法导出的解决方法

phpexcel无法导出的解决方法

 set_time_limit(0);
 ini_set("memory_limit","512M");

//去除符号 有些特别的符号 没办法导出来的

 function match_chinese($chars,$encoding='utf8')
    {
        $pattern =($encoding=='utf8')?'/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u':'/[\x80-\xFF]/';
        preg_match_all($pattern,$chars,$result);
        $temp =join('',$result[0]);
        return $temp;
    }

jquery swiper入场和出场动画

jquery swiper入场和出场动画

<!DOCTYPE html>
<html>
<head>
    ...
    <link rel="stylesheet" href="path/to/swiper.min.css">
    <link rel="stylesheet" href="path/to/animate.min.css">
</head>
<body>
    ...
    <script src="path/to/swiper.min.js"></script>
    <script src="path/to/swiper.animate-twice.min.js"></script>
</body>
</html>
<script>        
  var mySwiper = new Swiper ('.swiper-container', {
  onInit: function(swiper){ //Swiper2.x的初始化是onFirstInit
    swiperAnimateCache(swiper); //隐藏动画元素 
    swiperAnimate(swiper); //初始化完成开始动画
  }, 
  onSlideChangeEnd: function(swiper){ 
    swiperAnimate(swiper); //每个slide切换结束时也运行当前slide动画
  } 
  })        
  </script>

<div class="swiper-slide a">
            <div class="ani" data-slide-in="at 500 from bounceInDown use swing during 500" data-slide-out="at 0 to fadeOutRight use swing during 1500 force">内容1</div>
        </div>

4.说明

在每个要动画的类上面添加一个 ani的类名 然后在后面的DATA内 多了两个参数 data-slide-in 进场动画和 data-slide-out出场动画
参数是一致的。

at 500 from bounceInRight use swing during 500
在 多少时间开始 以 什么动画 使用 什么速度 动画用时 多少 (force 是否使用 只在出场的时候判断)

at 后面跟的是 动画延迟时间
from 后面跟的是 动画样式
use 后面跟的是 动画力度
during 后面跟的是 动画持续时间
force 后面跟的是 是否使用 只有在出场动画的时候使用。进场动画无效。。
出场动画执行时间 =进场等待时间(at)+进场动画执行时间(during)+出场等待时间(at)