Wednesday, June 06, 2018

网站应用微信登录开发指南

网站应用微信登录开发指南

准备工作

网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

授权流程说明

微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
获取access_token时序图:
第一步:请求CODE
第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。
参数说明
参数是否必须说明
appid应用唯一标识
redirect_uri请使用urlEncode对链接进行处理
response_type填code
scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即
state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
返回说明
用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE
请求示例
登录一号店网站应用
https://passport.yhd.com/wechat/login.do
打开后,一号店会生成state参数,跳转到
https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect
微信用户使用微信扫描二维码并且确认登录后,PC端会跳转到
https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e
为了满足网站更定制化的需求,我们还提供了第二种获取code的方式,支持网站将微信登录二维码内嵌到自己页面中,用户使用微信扫码授权后通过JS将code返回给网站。
JS微信登录主要用途:网站希望用户在网站内就能完成登录,无需跳转到微信域下登录后再返回,提升微信登录的流畅性与成功率。 网站内嵌二维码微信登录JS实现办法:
步骤1:在页面中先引入如下JS文件(支持https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
步骤2:在需要使用微信登录的地方实例以下JS对象:
 var obj = new WxLogin({
 self_redirect:true,
 id:"login_container", 
 appid: "", 
 scope: "", 
 redirect_uri: "",
  state: "",
 style: "",
 href: ""
 });
参数说明
参数是否必须说明
self_redirecttrue:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
id第三方页面显示二维码的容器id
appid应用唯一标识,在微信开放平台提交应用审核通过后获得
scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
redirect_uri重定向地址,需要进行UrlEncode
state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
style提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ
href自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ
第二步:通过code获取access_token
通过code获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数说明
参数是否必须说明
appid应用唯一标识,在微信开放平台提交应用审核通过后获得
secret应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code填写第一步获取的code参数
grant_type填authorization_code
返回说明
正确的返回:
{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
参数说明
参数说明
access_token接口调用凭证
expires_inaccess_token接口调用凭证超时时间,单位(秒)
refresh_token用户刷新access_token
openid授权用户唯一标识
scope用户授权的作用域,使用逗号(,)分隔
unionid当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
刷新access_token有效期
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
请求方法
获取第一步的code后,请求以下链接进行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数说明
参数是否必须说明
appid应用唯一标识
grant_type填refresh_token
refresh_token填写通过access_token获取到的refresh_token参数
返回说明
正确的返回:
{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN", 
"openid":"OPENID", 
"scope":"SCOPE" 
}
参数说明
参数说明
access_token接口调用凭证
expires_inaccess_token接口调用凭证超时时间,单位(秒)
refresh_token用户刷新access_token
openid授权用户唯一标识
scope用户授权的作用域,使用逗号(,)分隔
错误返回样例:
{"errcode":40030,"errmsg":"invalid refresh_token"}
注意:
1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。

建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。
第三步:通过access_token调用接口
获取access_token后,进行接口调用,有以下前提:
1. access_token有效且未超时;
2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
对于接口作用域(scope),能调用的接口有以下:
授权作用域(scope)接口接口说明
snsapi_base/sns/oauth2/access_token通过code换取access_token、refresh_token和已授权scope
snsapi_base/sns/oauth2/refresh_token刷新或续期access_token使用
snsapi_base/sns/auth检查access_token有效性
snsapi_userinfo/sns/userinfo获取用户个人信息
其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。
接口调用方法可查阅《微信授权关系接口调用指南》
F.A.Q
  1. 什么是授权临时票据(code)?
    答:第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次保障了微信授权登录的安全性。第三方可通过使用https和state参数,进一步加强自身授权登录的安全性。
  2. 什么是授权作用域(scope)?
    答:授权作用域(scope)代表用户授权给第三方的接口权限,第三方应用需要向微信开放平台申请使用相应scope的权限后,使用文档所述方式让用户进行授权,经过用户授权,获取到相应access_token后方可对接口进行调用。
  3. 网站内嵌二维码微信登录JS代码中style字段作用?
    答:第三方页面颜色风格可能为浅色调或者深色调,若第三方页面为浅色背景,style字段应提供"black"值(或者不提供,black为默认值),则对应的微信登录文字样式为黑色。相关效果如下:
若提供"white"值,则对应的文字描述将显示为白色,适合深色背景。相关效果如下:
4.网站内嵌二维码微信登录JS代码中href字段作用?
答:如果第三方觉得微信团队提供的默认样式与自己的页面样式不匹配,可以自己提供样式文件来覆盖默认样式。举个例子,如第三方觉得默认二维码过大,可以提供相关css样式文件,并把链接地址填入href字段
.impowerBox .qrcode {width: 200px;}
.impowerBox .title {display: none;}
.impowerBox .info {width: 200px;}
.status_icon {display: none}
.impowerBox .status {text-align: center;}
相关效果如下:

Tuesday, May 29, 2018

Reference:
https://www.jianshu.com/p/012223103355

http://www.ecma-international.org/ecma-262/5.1/#sec-12.4

js基础知识---call,apply,bind的用法

96
小兴nice 
2017.04.09 00:36* 字数 1858 阅读 736评论 2
call,apply详解
javascript中,call和apply方法的用途是为了扩充函数赖以生存的作用域,通俗点来说,就是为了动态改变函数体内部this的指向。
用途: 扩充函数赖以生存的作用域。
好处: 对象与方法之间不需要任何的耦合关系。
javascript的一大特点是,函数存在定义时上下文运行时上下文,和上下文是可变的,这样的概念。
先上一个例子:
function showColor(){
    console.log("my color is:" + this.color);
}
window.color = "red";

showColor.call(window);    //my color is:red
上面的例子中,shouwColor函数并没有对外部调用自己传入的参数进行接收,那么调用者是怎么样通过调用该函数来得到想要的结果呢?
先来解释下,上面这段代码。代码中,定义了一个showColor函数,以及一个挂载在window下的一个全局对象color,showColor.call(this)执行了shouwColor函数,并且改变了shouwColor函数中this的指向,call方法传入的第一个参数,始终代表着this的指向。当传入的第一个参数是window的时候,shouwColor函数中的this就指向了window,那么this.color就相当于window.colorl了,打印出来的结果就自然是window.color的值了。
var colorObj = {"color":"blue"};
showColor.call(colorObj);    //my color is:blue
那么我们再来定义一个colorObj 对象,对象中,有一个属性color,call方法中第一个参数是colorObj 对象,那么一样的道理,shouwColor函数中的this就指向了**colorObj **对象了。这就是call方法的简单运用了。
call,apply方法的定义
call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 window 对象被用作 thisObj。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 window 对象将被用作 thisObj, 并且无法被传递任何参数。
call,apply方法的区别
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:
function test(arg1,arg2){
    ......
}
就可以通过以下方式调用了
test.call(this,arg1,arg2);
test.apply(this,[arg1,arg2]);
其中 this 是你想指定的上下文,可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
call,apply方法的示例
1.数组的合并
var facebookImg = ["fb1.jpg","fb2.jpg","fb3.jpg"];
var youtubeImg = ["yt1.jpg","yt2.jpg","yt3.jpg"];
Array.prototype.push.apply(facebookImg,youtubeImg); //返回值为合并后的facebookImg数组的长度
facebookImg的值为: ["fb1.jpg","fb2.jpg","fb3.jpg","yt1.jpg","yt2.jpg","yt3.jpg"]
或者合并后赋值给一个新数组(不改变原数组的值)
var facebookImg = ["fb1.jpg","fb2.jpg","fb3.jpg"];
var youtubeImg = ["yt1.jpg","yt2.jpg","yt3.jpg"];
var allImg = [];
allImg.push.apply(allImg,facebookImg);
allImg.push.apply(allImg,youtubeImg);
2.获取数组中的最大值和最小值
js获取数组中的最大值和最小值,有多种方法,比如冒泡排序等,使用apply和call方法也是可以达到相同的效果的。
var  numbers = [5, 458 , 120 , -215 ]; 
var applyMaxInNumbers = Math.max.apply(Math, numbers);   //458
var applyMinInNumbers = Math.min.apply(Math,numbers); //-215
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。
3.类(伪)数组使用数组方法
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。
4.定义一个 log 方法,让它可以代理 console.log 方法
一般我们都会去这样的实现:
function log(msg){
    console.log(msg);
}
log("testData1");          //testData1
log("data1","data2");      //data1
上面的这种实现的方式在传入一个参数的时候是满足要求的,但是当传入的参数是多个的话,就失效了,因为log方法只接受了第一个且唯一一个参数。那么如果要在传入多个参数的情况下也能够实现,就可以用到call和apply方法了,注意,当不清楚参数的具体个数时,建议最好运用apply方法。
function log(){
    console.log.apply(window,arguments);
}
log("testData1");          //testData1
log("data1","data2","data3");      //data1,data2,data3
接下来的要求是给每一个 log 消息添加一个"(doView)"的前辍,比如:
log("hello world");    //(doView)hello world
那么就可以利用伪数组转为标准数组的方式,然后再使用unshift方法操作数组
function log(){
  var argsData = Array.prototype.slice.call(arguments);
  argsData.unshift('(doView)');
  console.log.apply(window, args);
};
5.借用构造函数继承的实现
javascript中的继承方式实现由多种,包括原型继承,借用构造函数继承与组合继承等。那么现在就用call和apply方法来简单实现下javascript中的构造函数的继承吧。
function superType(name){
    this.name = name;
}
function subType(name,age){
    this.age = age;
    superType.call(this,name);
}
var types1 = new subType("yqxcn", 30);
console.log("age:" + types1.age);        //age:30
console.log("name:" + types1.name);      //name:yqxcn,继承自superType属性值

var types2 = new subType("wx272252", 18);
console.log("age:" + types2.age);        //age:18
console.log("name:" + types2.name);      //name:wx272252,继承自superType属性值
bind的用法
bind方法虽然与call,apply的用法有点不同,但是其作用也是一样的,也是可以改变函数体内this的指向。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
以最开始的例子为例:
function showColor(){
    console.log("my color is:" + this.color);
}
window.color = "red";
showColor.bind(window);      //这里并不会打印出想要的结果
这个例子就可以很好的证明了上面MDN的解释了,当浏览器执行"showColor.bind(window); "这一句代码的时候,bind()创建了一个绑定函数,也就是说这句代码只是创建了一个函数,却并没有调用执行该函数,就像我们自己定义了一个普通函数而没有调用它,所以这句代码需要改成如下:
showColor.bind(window)();    //my color is:red
这也是apply、call、bind的不同之处。bind方法是创建一个函数,然后可以在需要调用的时候再执行函数,并非是立即执行函数;而call,apply是在改变了上下文中的this指向后并立即执行函数。
总结
  • call,apply,bind都是可以改变函数体内this的指向。
  • call,apply,bind使用时,传入的第一个参数都是用来传递this的指向的,也就是对上下文的指定。
  • call,apply,bind都是可以传入多个参数,不同的是,call和bind的后续参数都是按照顺序传参,而apply的传参类型是数组;bind的参数可以在函数执行的时候再次添加。
原创文章,站在前辈们的经验上的总结,文中如有不正之处,还望指正!

Monday, March 26, 2018

Centos目录-结构详细版

refference:
https://blog.csdn.net/daniel_fei/article/details/64495653
http://www.cnblogs.com/zsmynl/p/3602011.html

Centos目录结构详细版
目录详细介绍
n /: 根目录,一般根目录下只存放目录,不要存放文件,/etc/bin/dev/lib/sbin应该和根目录放置在一个分区中
n /bin:/usr/bin: 可执行二进制文件的目录,如常用的命令lstarmvcat等。
n /boot: 放置linux系统启动时用到的一些文件。/boot/vmlinuzlinux的内核文件,以及/boot/gurb。建议单独分区,分区大小100M即可
n /dev: 存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱mount /dev/cdrom /mnt
n /etc: 系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有/etc/inittab/etc/fstab/etc/init.d/etc/X11/etc/sysconfig/etc/xinetd.d修改配置文件之前记得备份。注:/etc/X11存放与x windows有关的设置。
n /home: 系统默认的用户家目录,新增用户账号时,用户的家目录都存放在此目录下,~表示当前用户的家目录,~test表示用户test的家目录。建议单独分区,并设置较大的磁盘空间,方便用户存放数据
n /lib:/usr/lib:/usr/local/lib: 系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助,比较重要的目录为/lib/modules
n /lost+fount: 系统异常产生错误时,会将一些遗失的片段放置于此目录下,通常这个目录会自动出现在装置目录下。如加载硬盘于/disk 中,此目录下就会自动产生目录/disk/lost+found
n /mnt:/media: 光盘默认挂载点,通常光盘挂载于/mnt/cdrom下,也不一定,可以选择任意位置进行挂载。
n /opt: 给主机额外安装软件所摆放的目录。如:FC4使用的Fedora 社群开发软件,如果想要自行安装新的KDE桌面软件,可以将该软件安装在该目录下。以前的 Linux 系统中,习惯放置在 /usr/local 目录下
n /proc: 此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的目录有/proc/cpuinfo/proc/interrupts/proc/dma/proc/ioports/proc/net/*
n /root: 系统管理员root的家目录,系统第一个启动的分区为/,所以最好将/root/放置在一个分区下。
n /sbin:/usr/sbin:/usr/local/sbin: 放置系统管理员使用的可执行命令,如fdiskshutdownmount等。与/bin不同的是,这几个目录是给系统管理员root使用的命令,一般用户只能"查看"而不能设置和使用。
n /tmp: 一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下
n /srv: 服务启动之后需要访问的数据目录,如www服务需要访问的网页数据存放在/srv/www
n /usr: 应用程序存放目录,/usr/bin 存放应用程序, /usr/share 存放共享数据,/usr/lib 存放不能直接运行的,却是许多程序运行所必需的一些函数库文件。/usr/local:存放软件升级包。/usr/share/doc: 系统说明文件存放目录。/usr/share/man: 程序说明文件存放目录,使用 man ls时会查询/usr/share/man/man1/ls.1.gz的内容建议单独分区,设置较大的磁盘空间
n /var: 放置系统执行过程中经常变化的文件,如随时更改的日志文件 /var/log/var/log/message: 所有的登录文件存放目录,/var/spool/mail: 邮件存放的目录, /var/run: 程序或服务启动后,其PID存放在该目录下。建议单独分区,设置较大的磁盘空间

Monday, February 26, 2018

centos6 下安装nginx1.7.9+php5.6.4+mysql5.6.2

FROM: http://www.vckai.com/p/31
该文章是由于我在docker安装LNMP环境时出现的,原型是张宴大哥这篇文章:http://zyan.cc/nginx_php_v7/,只是做了一些软件升级变更。

1. 安装关联库
# mkdir -p /data/tgz
# cd /data/tgz
# yum install wget
# yum install pcre
# yum install openssl*
# yum install tar
# yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers make gd gd2 gd-devel gd2-devel

# ulimit -SHn 65535
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz
# tar zxvf pcre-8.36.tar.gz
# cd pcre-8.36
# ./configure --prefix=/data/apps/pcre
# make && make install
# cd ../


2. 安装nginx
# /usr/sbin/groupadd nginx
# /usr/sbin/useradd -g nginx nginx

# wget http://nginx.org/download/nginx-1.7.9.tar.gz
# tar zxvf nginx-1.7.9.tar.gz
# cd nginx-1.7.9
# ./configure --user=nginx --group=nginx --prefix=/data/apps/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/data/tgz/pcre-8.36 --with-http_realip_module --with-http_image_filter_module
# make && make install
# cd ../

3. 安装MySQL
# /usr/sbin/groupadd mysql
# /usr/sbin/useradd -g mysql mysql

# wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.25-linux-glibc2.5-x86_64.tar.gz
# tar zxvf mysql-5.6.22-linux-glibc2.5-x86_64.tar.gz
# mv mysql-5.6.22-linux-glibc2.5-x86_64 /data/apps/mysql

    配置运行MySQL
    1)创建数据库存放目录
# mkdir -p /data/data/mysql/data
# mkdir -p /data/data/mysql/binlog/
# mkdir -p /data/data/mysql/relaylog/
# chown -R mysql:mysql /data/data/mysql/
# yum install libaio
    2)创建mysql配置文件
# vi /etc/my.cnf
        输入以下内容
[client]
port    = 3306
socket  = /tmp/mysql.sock

[mysqld]
character-set-server = utf8
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-ignore-db = information_schema
user    = mysql
port    = 3306
socket  = /tmp/mysql.sock
basedir = /data/apps/mysql
datadir = /data/data/mysql/data
log-error = /data/data/mysql/mysql_error.log
pid-file = /data/data/mysql/mysql.pid
open_files_limit    = 10240
back_log = 600
max_connections = 5000
max_connect_errors = 6000
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 300
#thread_concurrency = 8
query_cache_size = 512M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = MyISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 246M
max_heap_table_size = 246M
long_query_time = 3
log-slave-updates
log-bin = /data/data/mysql/binlog/binlog
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 1G
relay-log-index = /data/data/mysql/relaylog/relaylog
relay-log-info-file = /data/data/mysql/relaylog/relaylog
relay-log = /data/data/mysql/relaylog/relaylog
expire_logs_days = 30
key_buffer_size = 256M
read_buffer_size = 1M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover

interactive_timeout = 120
wait_timeout = 120

skip-name-resolve
#master-connect-retry = 10
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396

server-id = 1

innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 512M
innodb_data_file_path = ibdata1:256M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_log_file_size = 128M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0

slow-query-log-file = /data/data/mysql/slow.log
long_query_time = 10

[mysqldump]
quick
max_allowed_packet = 32M
    3)以mysql用户帐号的身份建立数据表
# /data/apps/mysql/scripts/mysql_install_db --basedir=/data/apps/mysql --datadir=/data/data/mysql/data --user=mysql
# sed -i "s#/usr/local/mysql#/data/apps/mysql#g" /data/apps/mysql/bin/mysqld_safe
    4)创建mysql启动,重启,停止shell脚本
# vi /data/apps/mysql/mysql
        输入以下内容(这里的用户名admin和密码12345678接下来的步骤会创建)
#!/bin/sh

mysql_port=3306
mysql_username="admin"
mysql_password="12345678"

function_start_mysql()
{
    printf "Starting MySQL...\n"
    /bin/sh /data/apps/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf 2>&1 > /dev/null &
}

function_stop_mysql()
{
    printf "Stoping MySQL...\n"
    /data/apps/mysql/bin/mysqladmin -u ${mysql_username} -p${mysql_password} -S /tmp/mysql.sock shutdown
}

function_restart_mysql()
{
    printf "Restarting MySQL...\n"
    function_stop_mysql
    sleep 5
    function_start_mysql
}

function_kill_mysql()
{
    kill -9 $(ps -ef | grep 'bin/mysqld_safe' | grep ${mysql_port} | awk '{printf $2}')
    kill -9 $(ps -ef | grep 'libexec/mysqld' | grep ${mysql_port} | awk '{printf $2}')
}

if [ "$1" = "start" ]; then
    function_start_mysql
elif [ "$1" = "stop" ]; then
    function_stop_mysql
elif [ "$1" = "restart" ]; then
function_restart_mysql
elif [ "$1" = "kill" ]; then
function_kill_mysql
else
    printf "Usage: /data/data/mysql/mysql {start|stop|restart|kill}\n"
fi
    5)赋予shell脚本可执行权限
# chmod +x /data/apps/mysql/mysql
    6)启动MySQL
# /data/apps/mysql/mysql start
    7)通过命令行登录管理MySQL服务器(提示输入密码时直接回车)
# /data/apps/mysql/bin/mysql -uroot -p -S /tmp/mysql.sock
    8)输入以下SQL语句,创建一个具有root权限的用户(admin)和密码(12345678)
> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY '12345678';
> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'127.0.0.1' IDENTIFIED BY '12345678';
> quit
blob.png
    9)(可选)重启/停止MySQL
# /data/apps/mysql/mysql restart
# /data/apps/mysql/mysql stop

4. 编译安装PHP依赖库
# mkdir -p /data/apps/libs/

# wget http://www.ijg.org/files/jpegsrc.v9.tar.gz   
# tar zxvf jpegsrc.v9.tar.gz
# cd jpeg-9/
# ./configure --prefix=/data/apps/libs --enable-shared --enable-static
# make && make install
# cd ../

# wget http://prdownloads.sourceforge.net/libpng/libpng-1.6.2.tar.gz
# tar zxvf libpng-1.6.2.tar.gz
# cd libpng-1.6.2/
# ./configure --prefix=/data/apps/libs
# make && make install
# cd ../

# wget http://download.savannah.gnu.org/releases/freetype/freetype-2.4.12.tar.gz
# tar zxvf freetype-2.4.12.tar.gz
# cd freetype-2.4.12/
# ./configure --prefix=/data/apps/libs
# make && make install
# cd ../


# wget --content-disposition "http://downloads.sourceforge.net/mhash/mhash-0.9.9.9.tar.gz?big_mirror=0"
# wget --content-disposition "http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz?big_mirror=0"
# wget --content-disposition "http://downloads.sourceforge.net/mcrypt/mcrypt-2.6.8.tar.gz?big_mirror=0"

# tar zxvf libmcrypt-2.5.8.tar.gz
# cd libmcrypt-2.5.8/
# ./configure --prefix=/data/apps/libs
# make && make install
# cd libltdl/
# ./configure --prefix=/data/apps/libs --enable-ltdl-install
# make && make install
# cd ../../

# tar zxvf mhash-0.9.9.9.tar.gz
# cd mhash-0.9.9.9/
# ./configure --prefix=/data/apps/libs
# make && make install
# cd ../

# vi /etc/ld.so.conf
        在文件末尾添加以下内容
/data/apps/libs/lib
        重新加载该文件,使其即刻生效
# ldconfig
# tar zxvf mcrypt-2.6.8.tar.gz
# cd mcrypt-2.6.8/
# export LDFLAGS="-L/data/apps/libs/lib -L/usr/lib"
# export CFLAGS="-I/data/apps/libs/include -I/usr/include"
# touch malloc.h
# ./configure --prefix=/data/apps/libs --with-libmcrypt-prefix=/data/apps/libs
# make && make install
# cd ../

5. 安装PHP
# wget --content-disposition http://cn2.php.net/get/php-5.6.4.tar.gz/from/this/mirror
# tar zxvf php-5.6.4.tar.gz
# cd php-5.6.4/
# export LIBS="-lm -ltermcap -lresolv"
# export DYLD_LIBRARY_PATH="/data/apps/mysql/lib/:/lib/:/usr/lib/:/usr/local/lib:/lib64/:/usr/lib64/:/usr/local/lib64"
# export LD_LIBRARY_PATH="/data/apps/mysql/lib/:/lib/:/usr/lib/:/usr/local/lib:/lib64/:/usr/lib64/:/usr/local/lib64"
# ./configure --prefix=/data/apps/php --with-config-file-path=/data/apps/php/etc --with-mysql=/data/apps/mysql --with-mysqli=/data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/data/apps/libs --with-jpeg-dir=/data/apps/libs --with-png-dir=/data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts
# make && make install
# cp php.ini-development /data/apps/php/etc/php.ini
# cd ../

6. 安装PHP扩展
# wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz
# tar zxvf autoconf-latest.tar.gz
# cd autoconf-2.69/
# ./configure --prefix=/data/apps/libs
# make && make install
# cd ../

# wget http://pecl.php.net/get/memcache-2.2.7.tgz
# tar zxvf memcache-2.2.7.tgz
# cd memcache-2.2.7/
# export PHP_AUTOCONF="/data/apps/libs/bin/autoconf"
# export PHP_AUTOHEADER="/data/apps/libs/bin/autoheader"
# /data/apps/php/bin/phpize
# ./configure --with-php-config=/data/apps/php/bin/php-config
# make && make install
# cd ../
blob.png

    1)php.ini配置文件中添加memcache扩展
# vi /data/apps/php/etc/php.ini
        在文件末尾添加以下内容
extension_dir="/data/apps/php/lib/php/extensions/no-debug-zts-20131226/"
extension=memcache.so

7. 启动nginx+php
    mysql的启动就不在这里多说,可参考上面。
    1)调整nginx配置文件(这里只是最简单的可运行php的nginx的配置,详细的自行)
# mv /data/apps/nginx/conf/nginx.conf /data/apps/nginx/conf/nginx.conf.default
# vi /data/apps/nginx/conf/nginx.conf
        输入以下内容
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
 root /data/www;

        location / {
            index  index.html index.htm index.php;
        }

        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi.conf;
        }
    }
}
    2)创建web目录
# mkdir -p /data/www
# chown -R nginx:nginx /data/www
    3)启动nginx
# /data/apps/nginx/sbin/nginx
    4)启动php-fpm
# /data/apps/php/sbin/php-fpm
OK,现在已经安装完成了,可以在浏览器中输入http://localhost访问你的网站了!

Thursday, January 15, 2015

submit a file or form with iframe in javascript

 $('#ad6 #uploaddatabtn').click(function(){
  console.dir('------EthanYen M9505506@gmail.com------')
   var iframe = $('');
            $("body").append(iframe);
            var form = $('#formSend2');
            form.attr("action", "./api/contentInput2.php");
            form.attr("method", "POST");
            form.attr("encoding", "multipart/form-data");
            form.attr("enctype", "multipart/form-data");
            form.attr("target", "tempIframe");
            //form.attr("file", $('#userfile').val());
            form.submit();
            $("#tempIframe").load(function () {
                iframeContents = this.contentWindow.document.body.innerHTML;
                console.dir(iframeContents)
                $(iframe).remove()
                $("#textarea").html(iframeContents);
            });
            //return false;
 })

Wednesday, December 24, 2014

HBL

http://yahoo-hbl.tumblr.com/ 我們做的,請參與,謝謝各位。

Friday, September 12, 2014

CSS transform AND jquery animate

-----------------------------------------------
<style>
#aa{
width:100%;
height:100%;
background: url('http://33.media.tumblr.com/f23c9636cd9fe74fa473492fa3d9f2d0/tumblr_nbru71s6AD1tlk8p6o1_500h.jpg') 0 0 no-repeat;
text-indent: 980px;
}
</style>
<!--<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>>-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$( "#aa" ).animate({
textIndent:0
}, {
duration: 5000,
step: function( now, fx ) {

$(this).css('transform','rotateX(' + now +'deg)')
$(this).css('transform', 'translate3d('+now+','+now+','+now+')');
//$(this).css('transform','rotateY(' + now +'deg)')
var data = fx.elem.id + " " + fx.prop + ": " + now;
$( "body" ).append( "<div>" + data + "</div>" );
}
});
})
</script>
<div id='aa'>

</div>

Monday, May 19, 2014

Json header and encode for PHP

link source: http://stackoverflow.com/questions/4064444/returning-json-from-a-php-script

PHP對JSON編碼後,送回去的資料型態利用header定義好再送回。
$data = array('a'=>array(1,2,3,4,5,6),'b'=>'bcd')/** whatever you're serializing **/;
header('Content-Type: application/json');
echo json_encode($data);