孙肖宁 发布的文章

微信公众号开发之自动回复。
首先看下文档,用户关注公众号之后,会发送一段xml格式的文本给服务器。

<xml> 
    <ToUserName>< ![CDATA[toUser] ]></ToUserName>  
    <FromUserName>< ![CDATA[fromUser] ]></FromUserName>  
    <CreateTime>1348831860</CreateTime>  
    <MsgType>< ![CDATA[text] ]></MsgType>  
    <Content>< ![CDATA[this is a test] ]></Content>  
    <MsgId>1234567890123456</MsgId>  
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方帐号(一个OpenID)
CreateTime消息创建时间 (整型)
MsgTypetext
Content文本消息内容
MsgId消息id,64位整型

回复消息给用户同样也是一段xml

<xml> 
    <ToUserName>< ![CDATA[toUser] ]></ToUserName> 
    <FromUserName>< ![CDATA[fromUser] ]></FromUserName>
    <CreateTime>12345678</CreateTime> 
    <MsgType>< ![CDATA[text] ]></MsgType> 
    <Content>< ![CDATA[你好] ]></Content> 
</xml>
参数是否必须说明
ToUserName接收方帐号(收到的OpenID)
FromUserName开发者微信号
CreateTime消息创建时间 (整型)
MsgTypeimage
MediaId通过素材管理中的接口上传多媒体文件,得到的id。

示例代码(thinkphp3.2.3)

<?php
namespace Wx\Controller;
use Think\Controller;
class IndexController extends Controller {
    public function index(){
        //获得参数 signature nonce token timestamp echostr
        $nonce     = $_GET['nonce'];
        $token     = 'xxxx';
        $timestamp = $_GET['timestamp'];
        $echostr   = $_GET['echostr'];
        $signature = $_GET['signature'];
        //形成数组,然后按字典序排序
        $array = array();
        $array = array($nonce, $timestamp, $token);
        sort($array);
        //拼接成字符串,sha1加密 ,然后与signature进行校验
        $str = sha1( implode( $array ) );
        if( $str  == $signature && $echostr ){
            //第一次接入weixin api接口的时候
            echo  $echostr;
            exit;
        }else{
            $this->reponseMsg();
        }
    }
    public function reponseMsg(){
        //1.获取到微信推送过来post数据(xml格式)
        $postArr = $GLOBALS['HTTP_RAW_POST_DATA'];
        //2.处理消息类型,并设置回复类型和内容
        $postObj = simplexml_load_string( $postArr );//xml转换成对象
        //$postObj->ToUserName
        //判断该数据包是否是订阅的事件推送
        if( strtolower( $postObj->MsgType) == 'event'){
            //如果是关注 subscribe 事件
            if( strtolower($postObj->Event == 'subscribe') ){
                //回复用户消息(纯文本格式)    
                $toUser   = $postObj->FromUserName;
                $fromUser = $postObj->ToUserName;
                $time     = time();
                $msgType  =  'text';
                $content  = '欢迎关注我们的微信公众账号';
                $template = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Content><![CDATA[%s]]></Content>
                            </xml>";
                $info     = sprintf($template, $toUser, $fromUser, $time, $msgType, $content);
                echo $info;
            }
        }
    }
}

首先安装插件sftp,详情请访问Sublime Text3常用插件以及安装方法
点击文件->SFTP/FTP->Setup Server
1.png
然后就会自动生成sftp-config.json的配置文件,然后再填写配置文件就可以了。

  • 填入你服务器的ip地址host
  • 用户名user
  • 密码password
  • 路径remote_path
    2.png
    保存之后就配置完毕了。
    上传文件的时候,只需要在要上传的文件或者文件夹上面点击鼠标右键,选择SFTP/FTP,再选择Upload Folder。选择下载,也可以把服务器端的文件下载到本地。

第一步:拥有自己的公众号以及服务器(及域名)。
第二步:申请测试账号,一定记住开发者密码(AppSecret),不然就只能重置了。
第三步:进入微信公共平台,点击开发->基本配置->服务器配置->修改规则
填入以下信息
1.png

URL:就是你的服务器的URL(要能响应TOKEN验证,还要能在外网访问到这个服务器)

TOKEN:这个算是自己设置的一个验证码,要自己在代码里面设置的(并且当微信服务器器把GET请求发到你的服务器的时候,能返回这个值)

注:微信服务器的GET请求会带四个参数signature,token,timestamp,echostr;POST请求会带三个参数除了刚才的echostr

  • 获得参数 signature nonce token timestamp echostr
  • 形成数组,然后按字典序排序
  • 拼接成字符串,sha1加密 ,然后与signature进行校验
    实例代码:

    <?php
    /**
    * wechat php test
    */
    
    //define your token;TOKEN一定和你自己的对应起来
    define("TOKEN", "weixin");
    $wechatObj = new wechatCallbackapiTest();
    $wechatObj->valid();
    
    class wechatCallbackapiTest
    {
      public function valid()
      {
          $echoStr = $_GET["echostr"];
    
          //valid signature , option
          if($this->checkSignature()){
              echo $echoStr;
              exit;
          }
      }
    
      public function responseMsg()
      {
          //get post data, May be due to the different environments
          $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
    
            //extract post data
          if (!empty($postStr)){
                  /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
                     the best way is to check the validity of xml by yourself */
                  libxml_disable_entity_loader(true);
                    $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                  $fromUsername = $postObj->FromUserName;
                  $toUsername = $postObj->ToUserName;
                  $keyword = trim($postObj->Content);
                  $time = time();
                  $textTpl = "<xml>
                              <ToUserName><![CDATA[%s]]></ToUserName>
                              <FromUserName><![CDATA[%s]]></FromUserName>
                              <CreateTime>%s</CreateTime>
                              <MsgType><![CDATA[%s]]></MsgType>
                              <Content><![CDATA[%s]]></Content>
                              <FuncFlag>0</FuncFlag>
                              </xml>";             
                  if(!empty( $keyword ))
                  {
                        $msgType = "text";
                      $contentStr = "Welcome to wechat world!";
                      $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                      echo $resultStr;
                  }else{
                      echo "Input something...";
                  }
    
          }else {
              echo "";
              exit;
          }
      }
          
      private function checkSignature()
      {
          // you must define TOKEN by yourself
          if (!defined("TOKEN")) {
              throw new Exception('TOKEN is not defined!');
          }
          
          $signature = $_GET["signature"];
          $timestamp = $_GET["timestamp"];
          $nonce = $_GET["nonce"];
                  
          $token = TOKEN;
          $tmpArr = array($token, $timestamp, $nonce);
          // use SORT_STRING rule
          sort($tmpArr, SORT_STRING);
          $tmpStr = implode( $tmpArr );
          $tmpStr = sha1( $tmpStr );
          
          if( $tmpStr == $signature ){
              return true;
          }else{
              return false;
          }
      }
    }
    
    ?>

EncodingAeskey:直接点击随机生成就好了。

提交之后,会提醒你配置成功。

  • 获得服务器的操作系统: <?PHP echo PHP_OS; ?>
  • 服务器端信息:<?PHP echo $_SERVER ['SERVER_SOFTWARE']; ?>
  • 服务器剩余空间大小:<?PHP echo disk_free_space("/目录"); ?>字节
  • 最大执行时间:<?PHP echo get_cfg_var("max_execution_time")."秒 "; ?>
  • 脚本运行占用最大内存:<?PHP echo get_cfg_var ("memory_limit")?get_cfg_var("memory_limit"):"无" ?>
  • 最大上传限制:<?PHP echo get_cfg_var ("upload_max_filesize")?get_cfg_var ("upload_max_filesize"):"不允许上传附件"; ?>
  • 服务器php版本:<?PHP echo PHP_VERSION; ?>
  • ZEND版本:<?PHP echo zend_version(); ?>
  • mysql版本:<?php @mysql_connect("127.0.0.1", "root", "root"); echo mysql_get_server_info(); ?>
  • MySQL最大连接数: <?php echo @get_cfg_var("mysql.max_links")==-1 ? "不限" : @get_cfg_var("mysql.max_links"); ?>
  • MySQL数据库持续连接:<?php echo @get_cfg_var("mysql.allow_persistent")?"是 ":"否"; ?>

附录:php中的header
浏览器访问http服务器,接收到响应时,会根据响应报文头的内容进行一些具体的操作,在php中,我们能够使用 header来设置这些内容

设置文本编码

设置编码格式为:utf-8
header('content-type:text/html; charset= utf-8');

设置页面跳转:设置跳转到百度首页
header('location:http://www.baidu.com');
设置页面间隔刷新
header('refresh:3; url=http://www.xiaomi.com');

动画是CSS3中具有颠覆性的特征之一,可通过设置多个节点来精确控制一个或一组动画,常用来实现复杂的动画效果。
1、必要元素:
a、通过@keyframes指定动画序列;
b、通过百分比将动画序列分割成多个节点;
c、在各节点中分别定义各属性
d、通过animation将动画应用于相应元素;
2、关键属性
a、animation-name设置动画序列名称。
b、animation-duration动画持续时间。
c、animation-delay动画延时时间。
d、animation-timing-function动画执行速度,linear、ease等。
e、animation-play-state动画播放状态,running、paused等。
f、animation-direction动画逆播,alternate等。
g、animation-fill-mode动画执行完毕后状态,forwards、backwards等。
h、animation-iteration-count动画执行次数,inifinate等。
i、steps(60) 表示动画分成60步完成。
参数值的顺序:关于几个值,除了名字,动画时间,延时有严格顺序要求其它随意。
3、CSS3中的动画:
定义动画:

@keyframes 动画名{
     from{ 初始状态}
       to{结束状态}
}

调用:基本语法格式
animation: 动画名称 持续时间;

那一年
我在蹒跚学步你小学
我为一颗糖和你起争执
我的记忆里没有你

那一年
我小学你中学
我在田间小路等你回家
我的记忆里没有你

那一年
我中学你大学
我在哭泣和不舍中看你离开
我的记忆里没有你

和你的争执
漫长的等待
不舍的别离
却成了仅存的记忆
我的记忆里没有你

2D转换

转换是CSS3中具有颠覆性的特征之一,可以实现元素的位移、旋转、变形、缩放,甚至支持矩阵方式,配合即将学习的过渡和动画知识,可以取代大量之前只能靠Flash才可以实现的效果。在css3 当中,通过transform(变形) 来实现2d 或者3d 转换,其中2d 有,缩放,移动,旋转。

  • 缩放 scale(x, y) 可以对元素进行水平和垂直方向的缩放,x、y的取值可为小数,不可为负值;
  • 移动 translate(x, y) 可以改变元素的位置,x、y可为负值;x 在水平方向移动。y 在垂直方向移动。

    • 移动位置相当于自身原来位置
    • 除了可以像素值,也可以是百分比,相对于自身的宽度或高度
  • 旋转 rotate(deg) 可以对元素进行旋转,正值为顺时针,负值为逆时针;

    • 当元素旋转以后,坐标轴也跟着发生的转变
    • 调整顺序可以解决,把旋转放到最后
  • 倾斜 skew(deg, deg) 可以使元素按一定的角度进行倾斜,可为负值,第二个参数不写默认为0。
  • 矩阵matrix() 把所有的2D转换组合到一起,需要6个参数.
    我们可以同时使用多个转换,其格式为:transform: translate() rotate() scale() ...等,其顺序会影响转换的效果。

    3D转换

    首先需要知道3D转换之后的坐标系。
    4.png

  • 绕X轴旋转, 3D转换-旋转rotateX
  • 绕Y轴旋转, 3D转换-旋转rotateY
  • 绕Z轴旋转, 3D转换-旋转rotateZ
  • 在X轴移动, 3D转换-移动translateX
  • 在Y轴移动, 3D转换-移动translateY
  • 在Z2轴移动,6 3D转换-移动translateZ

透视(perspective
电脑显示屏是一个2D平面,图像之所以具有立体感(3D效果),其实只是一种视觉呈现,通过透视可以实现此目的。
透视可以将一个2D平面,在转换的过程当中,呈现3D效果。
注:并非任何情况下需要透视效果,根据开发需要进行设置。
perspective有两种写法

  • 作为一个属性,设置给父元素,作用于所有3D转换的子元素。
  • 作为transform属性的一个值,做用于元素自身。

3D呈现(transform-style)
设置内嵌的元素在 3D 空间如何呈现,这些子元素必须为转换原素。
flat:所有子元素在 2D 平面呈现。
preserve-3d:保留3D空间。
3D转换-透视transform-style
3D元素构建是指某个图形是由多个元素构成的,可以给这些元素的父元素设置transform-style: preserve-3d来使其变成一个真正的3D图形。

backface-visibility设置元素背面是否可见。

transition

语法:transition:param1 param2

  • param1 要过渡的属性
  • param2 过渡的时间.

过渡是CSS3中具有颠覆性的特征之一,可以实现元素不同状态间的平滑过渡(补间动画),经常用来制作动画效果。
补间动画:自动完成从起始状态到终止状态的的过渡。不用管中间的状态
帧动画:扑克牌切换.通过一帧一帧的画面按照固定顺序和速度播放。
特点:当前元素只要有“属性”发生变化时,可以平滑的进行过渡。
transition-property设置过渡属性
transition-duration设置过渡时间 用来控制速度linear(匀速)ease-in (加速)ase-in-out (先加速后减速) ease-out (减速)
transition-timing-function设置过渡速度
transition-delay设置过渡延时,超过时间后执行动画.

最近有重新读了一遍《巴黎圣母院》。这本书给我留下了深刻的印象,使我受益匪浅,原因是:它让我看到了世间最深沉的灵魂最深沉的呼唤。
《巴黎圣母院》情节曲折、人物性格具有冲突性,是一部富有戏剧性的著作。小说揭露了宗教的虚伪,歌颂了下层劳动人民的善良、友爱、舍己为人的高贵品质,反映了雨果的人道主义思想。小说把美与丑进行了强烈对比,也让我更加明白了一个道理:外表美并不代表心灵美!

一、埋在宗教外衣下面的人性--克洛德
让我印象深刻的场景是作者笔下的那些建筑,那些奢华的象征权力的教堂,人们还不知道可以拥有自己的思想,以及为了自己的愿望可以做什么事情,一切都假借神圣的宗教,一切都假借神圣的教堂来展现,展现建筑家的审美观,也就是个人的才华,或者展示自己的能力。我想那时的人们,把人性深深地埋在一件神圣的宗教的外衣下面,典型的人物就是副主教--克洛德。从许多的错综复杂的毫无章法的建筑群,我们不难看出,当时人们的内心是怎样的压抑,怎样狂躁,那些像雨后春笋一般从地下冒出来的教堂的尖顶,正是人们扭曲的灵魂在对着苍天做无谓的哀嚎!!!
当故事的情节愈演愈烈时,我读懂了他精神世界中的畸形。他不择手段地“爱”,让他卑鄙地,变态地劫持爱斯梅拉达,并且因“爱”成恨地要置她于死地。这是一种自私的,低微的,霸道的“爱”,充满了病态的“爱”,那不算是爱,只是伤害。借助宗教的名义做自己的事,以控制人们的思想。使得社会笼罩在他的势力之下。看似对别人的好,到最后也成了伤害。

二、生活在黑暗世界的反抗--敲钟怪人卡西莫多
卡西莫多属于自身条件极差,但目光有非常高的幻想爱情主义的典范。他由于长相畸形,从小成为弃婴,是副教主克洛德收养了他。由于从小在教堂长大,他也从来没有享受过家庭的暖和。长大后,持续留在教堂做敲钟人,所以他爱的人只有两个,一个是副教主克洛德,一个是教堂的没有姓名的大众。卡西莫多外貌丑陋,但是他的内心却是高尚的。他勇敢地从封建教会的“虎口”中救出了爱斯梅拉达,用“圣殿避难”的方法保住了姑娘的姓名。可是,当漂亮仁慈的艾斯梅拉达呈现的时候,唤醒了他心坎对美妙爱情的盼望,然而这种美妙爱情的觉悟,并没有给他带来任何的快活,反而使他更加深入地感受到了胜利缺点带来的经历上的苦楚。面对艾丝美拉达的漂亮,他是那样的自卑,苦楚,他盼望接近艾丝美拉达,但是又怕自己的丑恶令艾丝美拉达难受和惧怕。他对爱斯梅拉达并没有什么奢望,他只要知道她在他身边就行了。然而就连这样一个奢望也被他的养父夺走了,失望中的卡西莫多愤怒的杀死了她的养父副教主克洛德,然后与艾丝美拉达一起去了另一个世界。永远守护在艾斯梅拉达的身边。
身在宗教势力的笼罩之下,使自己一直为宗教效力,当自己发现宗教的邪恶之时,当自己的最爱被自己爱戴的养父夺取时,出于对社会的屈服,使自己只能含恨离开这个世界,去和自己心爱的人去另一个世界去寻找幸福。如果敢于与宗教斗争,敢于去争取自己的爱情,哪怕最后牺牲,也不会在有什么遗憾了。

三、与丑对照的美--艾丝美拉达
代表美丽善良的姑娘--爱斯梅拉达。她不仅有迷人的外貌,更有一颗纯真善良的心灵,从她对待那只山羊,救下那个落魄的诗人,对于伤害过自己的卡西莫多,送上的水和怜悯,对待爱情的牺牲,等,我们看到她是美丽的,她的身上心灵上没有污垢,她是没有被污染的。可是,这样的天使一样的姑娘,受到的是怎么样的对待呢?流浪,在最肮脏的环境里面生活,被所谓的上流社会排斥和嘲讽,被玩弄,被抛弃,被诬陷,被威胁,最后,作了彻底的牺牲。她有菩萨一般无人能及的心肠,她有倾国倾城的美貌,她是善与美的化身!
她善良,美丽充满了同情心,但在宗教的影响下,她的所作所为都不为人们所接纳,人们只信仰宗教,致使自己最后也无法逃脱宗教的迫害,使得自己与自己心爱的人不得不逃离现实的世界,她的所作所为从侧面展现了宗教对人们的迫害,对人们思想的钳制。同时也说明了在那种宗教的影响下,善和美还是存在的,在人民身边也能感受到,只是等待人们的传播与发扬。当她的善良感化了身边的每个人,那么结局将会是一个美好的结局。
书中描写了一个那样的社会,和在那个社会生活中的种种人物的状态,麻木的如那个弗比斯,最底层的如老鼠洞里的那几个隐修女,疯狂的副主教,还有尽全力反抗的最丑陋的卡齐莫多,副主教和卡齐莫多形成了人性上的鲜明对比,同样爱上了美丽的姑娘,同样的遭到了拒绝,他们的爱都是那么的热烈,那么的诚挚,可是,一个是占有,一个是奉献,已占有为目的的,当目的无法达到的时候,他想到的是毁灭,毁灭别人;以奉献为目的的,当无法奉献的时候,想到的也是毁灭,毁灭自己。
我一直思考着:为什么在追求欢乐的同时,隐藏着悲痛的灵魂,世道如此吧!在生活中总有艰难,总有困惑,也会有成功,更会有失败……

背景在CSS3中也得到很大程度的增强,比如背景图片尺寸、背景裁切区域、背景定位参照点、多重背景等。

  • background-size:width,height 可以设置背景图片的宽度以及高度

    • background-size设置背景图片的尺寸
      background-size: 100% auto; 自动是适应盒子的宽度,当宽度发送改变时,高度会有内容溢出。
      常规用法:通过百分百,和像素来调整背景的尺寸.
    • cover会自动调整缩放比例,保证图片始终填充满背景区域,如有溢出部分则会被隐藏。整个背景图片完整显示在背景区域.
    • contain会自动调整缩放比例,保证图片始终完整显示在背景区域。也可以使用长度单位或百分比
  • background-origin(原点,起点)设置背景定位的原点

    • 所谓的背景原点就是调整背景位置的一个参照点.调整背景图片定位的参照原点.
    • border-box以边框做为参考原点;
    • padding-box以内边距做为参考原点;
    • content-box以内容区做为参考点;
  • background-clip设置背景区域clip(裁切)

    • border-box裁切边框以内为背景区域;
    • padding-box裁切内边距以内为背景区域;
    • content-box裁切内容区做为背景区域;
  • 以逗号分隔可以设置多背景,可用于自适应局
    背景图片尺寸在实际开发中应用十分广泛。