Thinkphp5(任何框架都可以)结合Ucenter在单页开发模式下实现相互通信的具体步骤[踩坑记](二)

上回说到在服务端出现通信成功 代表很重要的一步已经搞定了,可能在这个步骤中会出现很多坑,这里说几点

1.在nginx可能会出现显示一直正在连接中,导致后台卡死,百度过后这是在windins中的现象,换apache解决

2.出现通信失败一般的原因是key没有正确配置导致,注意检查每个客户端中的key是否和服务端中的配置一样

3.还有就是在他官方的示例代码中,有处代码错误,大致是没有配置数据库,会报错,大家找到加上就可以

服务端向客户端通信步骤

在阅读discuz源码后发现他实现同步登录其实就是调用uc_user_synlogin函数来生成一堆script代码,这些代码中src都是你服务端配置的各个应用的url/api.uc.php(在示例代码中更加容易看到)

uc_user_synlogin() 这个函数 代表着 要同步登陆到其他所有开启同步登陆的函数  uc自己会在后台把所有开启同步登陆的应用都给循环遍历一遍 然后 在页面上输出

<script type=”text/javascript” src=”xxxxxxxxxxxxxxxxxxxxxxxxx” reload=”1″></script>

<script type=”text/javascript” src=”xxxxxxxxxxxxxxxxxxxxxxxxx” reload=”1″></script>

发送给每个开启同步登陆的应用, 然后每个开启同步登陆的应用的回调文件 uc.php 接受到后会进行解密,解密好后其实你就可以自己来写代码了

这个图大家应该可以看的更加清楚,这是示例代码的例子:

然后我们在客户端uc.php中 执行自己逻辑,包含生成token、cookie之类的,下面示例代码是thinkphp5框架的大家可以参考

 //------------------------------------引入thinphp核心文件完成登录状态----------------------------------------
 // 引入核心文件
 require_once '../../simplewind/thinkphp/base.php';
 // 生成token文件
 require_once '../../app/common/logic/AuthManager.php';
 // 公共函数文件
 require_once '../../app/common.php';
 // 助手函数
 require_once '../../simplewind/thinkphp/helper.php';
 $bbs=\think\Db::connect([
 // 数据库类型
 'type' => 'mysql',
 // 服务器地址
 'hostname' => 'xxxxx',
 // 数据库名
 'database' => 'xxxx',
 // 数据库用户名
 'username' => 'xxx',
 // 数据库密码
 'password' => 'xxxx',
 // 数据库编码默认采用utf8
 'charset' => 'utf8',
 // 数据库表前缀
 'prefix' => 'pre_common_',
 ]);
 $res=$bbs->table('pre_ucenter_members')->where('uid',1)->field('uid,username')->find();
 $res['sid']=\app\common\logic\AuthManager::createKey('User',$res);
 setcookie('info',json_encode($res),time()+86400,'/','.yingyin.com');
 //----------------------end--------------------------

这里生成cookie 域名是.yingyin.com,这样设置是为了让我们cookie达到跨域效果

接下来在我们单页应用中 就可以通过判断这个cookie 来达到是否登录的目的

客户端向服务端通信步骤

只要弄明白服务端向客户端通信,这个就简单了

原理就是在我们登录接口中,使用uc_user_synlogin函数来生成通知代码,然后返回到网站上,网站通过接口拿到通知然后进行进行异步通知即可

大致代码如下

 

 //---------------------------登录通知_beg--------------------------------------------
 include_once CMF_ROOT.'/public/config.inc.php';
 include_once CMF_ROOT.'/public/include/db_mysql.class.php';
 include_once CMF_ROOT.'/public/uc_client/client.php';
 //用户登陆成功,设置 Cookie,加密直接用 uc_authcode 函数,用户使用自己的函数
 setcookie('Example_auth', uc_authcode($res['uid']."\t".$res['username'], 'ENCODE'));
 setcookie('Example_auth', '', -86400);
 //生成同步登录的代码
 $ucsynlogin = uc_user_synlogin($res['uid']);
 if (preg_match_all('/"http(.+?)"/', $ucsynlogin, $matches)) {
 foreach ($matches[0] as $k=>$v){
 $res['synlogin'][]=str_replace('"','',$v);
 }
 }
 //---------------------------登录通知_end--------------------------------------------

最后说

这个流程只是本人对ucenter的一些了解,当然可能不是最简单,大家其实只要明白了这个通信原理,结合自己框架代码,接口验证来完成自己的登录通信

Thinkphp5(任何框架都可以)结合Ucenter在单页开发模式下实现相互通信的具体步骤[踩坑记](一)

前言

Ucenter这个玩意貌似现在好久没有人研究了,不过没办法,最近有个项目中有三个vue开发的单页应用网站和已存在的论坛网站要实现登录通信,直白一点就是我在一个网站登录了,去访问其他网站我的登录状态还是存在的。

Ucenter是什么

UCenter 的中文意思就是“用户中心”,其中的 U 代表 User 也代表 You ,取其中的含义就是“用户中心”,或者说“你(最终用户)的中心”。 UCenter 是 Comsenz 旗下各个产品之间信息直接传递的一个桥梁,通过 UCenter 站长可以无缝整合 Comsenz 系列产品,实现用户的一站式注册、登录、退出以及社区其他数据的交互的php框架。

当然这是官方的解释,说白了就是统一用户中心,尤其对于discuz论坛结合其他产品的统一。

通信原理

首先让我们看一下他的目录结构

advanced文件下有相关接口文档、示例代码、和尤其重要的客户端文件uc_client

upload下面是服务端文件  里面有安装文件install  discuz论坛一般都会默认安装吧

其他文件不怎么重要也就不说了

 

 

 

 

 

Ucenter实现同步登陆的原理就是cookie,一个应用登陆成功之后,向Ucenter传递数据,让Ucenter通知其他的应用也设置cookie,这样用户在访问其他应用的时候通过已经设置好的cookie实现自动登陆。通知登录重要的一个函数就是uc_user_synlogin 他需要传递一个用户id   然后返回值会生成同步登录javascript代码,来达到通知效果,本篇文章不会采用他这种方式,因为我们网站是采用单页开发的。

安装服务端客户端文件 添加通信网站

安装服务端就不做过多介绍了,在你网站根目录下建个uc_server文件夹,然后把upload文件放进去,访问安装路径即可,他会在你数据库里面生成ucenter一些数据表,目录接口大致如如下

 

 

 

 

 

 

 

 

 

 

这是后台登录后的界面

 

 

 

 

 

 

 

 

重要的来了

重要的是安装客户端,然后在服务端后台里面添加应用实现通信成功

在你自己客户端项目里面加入以下文件

api/uc.php 就是他服务端默认回调的接口,他会请求你这个接口

include下面是操作数据库的实例

uc_client下是一些类库

config.inc.php 是通信相关的配置 包括key 和数据库 很重要

 

 

 

 

 

 

 

 

 

 

后台添加应用后 他会生成一个key,这个key很重要需要在客户端配置才能实现通信

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

我图中标红的都是一些重要参数

这是客户端填写key的地方包括应用ID   配置文件config.inc.php中

 

 

 

 

 

这个时候 刷新服务端 出现通信成功 第一步搞定了

由于内容比较多,下一步放到第二篇文章来继续

 

React Native组件生命周期

一、看图分析

      在下图中描述了React Native中组件的生命周期,我们可以根据其中的执行顺序在对应的函数中做对应的操作。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

如图,可以把组件生命周期大致分为三个阶段:

第一阶段:是组件第一次绘制阶段,如图中的上面虚线框内,在这里完成了组件的加载和初始化;
第二阶段:是组件在运行和交互阶段,如图中左下角虚线框,这个阶段组件可以处理用户交互,或者接收事件更新界面;
第三阶段:是组件卸载消亡的阶段,如图中右下角的虚线框中,这里做一些组件的清理工作。

其中最常用的为实例化阶段,该阶段就是组件的构建、展示时期,需要我们根据几个函数的调用过程,控制好组件的展示和逻辑的处理。

二、实例化阶段函数功能分析

getDefaultProps

该函数用于初始化一些默认的属性,通常会将固定的内容放在这个函数 中进行初始化和赋值;

在组件中,可以利用this.props获取在这里初始化它的属性,由于组件初始化后,再次使用该组件不会调用getDefaultProps函数,所以组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

getInitialState

该函数是用于对组件的一些状态进行初始化;

由于该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件的状态的一些变量放在这里初始化,如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值, 比如:

this.setState({
    activePage: activePage, 
    currentX: contentOffSetX  
});

注意:一旦调用了this.setState方法,组件一定会调用render方法,对组件进行再次的渲染,不过,如果React框架会自动根据DOM的状态来判断是否需要真正的渲染。

componentWillMount

相当于OC中的ViewWillAppear方法,在组件将要被加载在视图上之前调用,功能相对较少。

render

      render是一个组件中必须有的方法,本质上是一个函数,并返回JSX或其他组件来构成DOM,和Android的XML布局类似,注意:只能返回一个顶级元素 ;

此外,在render函数中,只可通过this.state和this.props来访问在之前函数中初始化的数据值 。

componentDidMount

       在调用了render方法后,组件加载成功并被成功渲染出来以后,所要执行的后续操作,一般会在这个函数中处理网络请求等加载数据的操作;

因为UI已经成功被渲染出来, 所以放在这个函数里进行请求操作,不会出现UI上的错误

三、存在期阶段函数功能分析

componentWillReceiveProps    

指父元素对组件的props或state进行了修改

shouldComponentUpdate    

一般用于优化,可以返回false或true来控制是否进行渲染

componentWillUpdate

组件刷新前调用,类似componentWillMount

componentDidUpdate

更新后的hook

四、销毁期阶段函数功能分析

用于清理一些无用的内容,如:点击事件Listener,只有一个过程:componentWillUnmount

 

Windows下搭建ReactNative安卓开发环境

前言

其实官方文档上已经很详细了,我这里只说一下要注意的细节和大致过程。其实最主要的是java的SDK

Python2

大家直接官网下载即可https://www.python.org/,需要注意的是目前ReactNative不支持Python 3版本

Node

继续官方下载安装即可:https://nodejs.org/en/

Android Studio

这个建议大家百度去下载,速度会快很多,Android Studio需要Java Development Kit [JDK] 1.8(暂不支持更高版本)官网下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

然后就是安装完后的设置的sdk目录一定要记住,如图

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

环境变量

ANDROID_HOME:指向了你安装的Android SDK的路径

JAVA_HOME:指向你安装java sdk的安装目录

将Android SDK的Tools目录添加到PATH变量中以便在终端中运行一些Android工具,例如android avd或是adb logcat等。

 

 

 

 

 

 

 

 

 

 

 

 

 

Genymotion模拟器

比起Android Studio自带的原装模拟器,Genymotion是一个性能更好的选择,但它只对个人用户免费,需要大家注册在下载,官网地址:https://www.genymotion.com/download

vue2 过滤器 | 过滤时间 Monent.js的使用

第一步:安装

npm install moment --save 

第二步:在main.js中引用

import moment from 'moment/moment'

第三步:在main.js中添加过滤器

Vue.filter('moment', function (value, formatString) {
    formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
    // return moment(value).format(formatString); // value可以是普通日期 20170723
    return moment.unix(value).format(formatString); // 这是时间戳转时间
});

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

第四步: 在vue页面中使用过滤器

<template>
  <div id="app">
      <div>
        {{ datetime | moment }}
      </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
    return {
      datetime: '1500799859'
    }
  }
}
</script>

elementUI Message 独立引入的用法

今天在做项目时候,用到了 elementUI 的 Message 组件。因为我是按需 import 引入的方法,结果按照原本的文档API代码不生效。

查看文档之后有俩种引入方法:

全局引入

import ElementUI from ‘element-ui’;

Vue.use(ElementUI);

按需引入

import { Button, Select } from ‘element-ui’;

Vue.use(Button)

Vue.use(Select)

简答来说,如果是全局引入的话,就可以直接使用this.$message,但是按需引入的话能不能像全局引入一样用 this.$message 呢?

问题原因及解决:

查看下 element-ui/package/message/index.js 的实现方法,结果发现:

import Message from './src/main.js';
export default Message;

直接返回了。

而其他的组件,一般都是有 install 方法供Vue来操作的。

知道问题所在就好解决了,给 Message 添加 install 方法就行了。

// 和其他组件一样,一并引入
import {Button, Message} from 'element-ui'

// 在调用 Vue.use 前,给 Message 添加 install 方法
Message.install = function (Vue, options) {
  Vue.prototype.$message = Message
}

// 和所有组件一样,一并进行use
Vue.use(Button)
Vue.use(Message)

当然,也可以不用 Vue.use 来实现,比如直接写在 Vue 实例上:

// 和其他组件一样,一并引入
import {Button, Message} from 'element-ui'

Vue.use(Button)

// 将 Message 直接挂在 Vue 实例上
Vue.prototype.$message = Message

linux环境安装php fileinfo扩展

windows环境安装扩展比较简单,只需要把dll拷贝到扩展目录,修改php.ini中相应的扩展就好了

1.我们从fileinfo的源码来安装这个扩展。fileinfo的源码在php源码的“src/ext/fileinfo”的目录下面,可以用find来找到具体的路径

find / -name fileinfo

2.cd 到该位置(根据自己的具体情况来)

cd /usr/local/src/php7/ext/fileinfo/

3.不要离开php安装源码的ext/fileinfo目录,执行以下命令

/usr/local/php/bin/phpize

4.执行

./configure --with-php-config=/usr/local/php/bin/php-config

注意这里面php-config=后面的是你php-config所在的路径,一定要填对
5.编译安装

make && make install  

6.进入php.ini,添加一句

extension=fileinfo.so  

7.重启PHP

/etc/init.d/php-fpm reload  

8.输出phpinfo(),出现下图表示安装成功