首页> 搜索结果页
"thinkphp 服务器 空白" 检索
共 14 条结果
ThinkPHP项目传到服务器 前台正常 后台空白不报错
后台手工 在网址输入Login/index 登录页面 可以正常登录 但是 进入Index/index 还是空白!
问答
PHP
2017-01-02
部署thinkphp3.1.2用php什么版本。。。
我的网站是thinkphp3.1.2弄的,,,现在想放到服务器上,但是我试了好多个镜像市场的镜像都访问不了,,页面就空白。一个版本是:操作系统:centos 6.3 64位 php运行环境(centos 6.3 64位 | php5.4 | apache2) 还有一个是:Apache2+php5.2+Mysql5+vsftpd 。。。。。。。。。。我想问,这是php版本的问题吗?各位大神求帮助
问答
Linux  ·  PHP
2015-07-04
thinkphp学习笔记3—项目编译和调试模式
原文:thinkphp学习笔记3—项目编译和调试模式 1.项目编译 在章节2.4项目编译中作者讲到使用thinkphp的项目在第一次运行的时候会吧核心需要加载的文件去掉空白和注释合并到一个文件中编译并缓存,第二次运行时直接载入编译缓存,这样省去一些IO开销,加快执行速度。并且在3.0以上的版本中海做了一些优化: 1.合并和兴编译缓存和项目编译缓存,不再生成两个缓存文件 2.直接对本地环境生成设置和常量定义减少环境判断 3.编译缓存可以直接替换框架入口甚至项目入口,甚至脱离框架独立运行 4.通过参数设置,生成的编译缓存载入外部的常量定义,便于产品用户定义 貌似高上大,后面继续讲在没有开启调试模式的情况下会在thinkphp\Application\Runtime目录下生成一个~runtime.php的文件,就是编译缓存文件。我实验了一下,在项目入口文件中有一句define('APP_DEBUG',True);修改成define('APP_DEBUG',False);,再次运行,在Runtime目录果然生成了一个类似文件,不过名称有点差别,是common~runtime.php,截图如下: 图1 打开这个common~runtime.php文件,我们可以看到内容是一行没有空格的代码,类似于压缩过的js代码,如下: 图2 注意环境改变之后这个缓存文件应该删除,不能把本地生成的编译缓存拷贝到其他服务器或者环境直接使用,只能再次生成。 编译缓存的内容包含:系统函数库,系统基础核心类库,扩展定义的核心行为类库,项目配置文件,项目函数文件。在项目入口文件中可以更改这个文件的生成目录例如: define('RUNTIME_PATH','./App/temp/'); 持此之外开可以弟子你故意缓存文件名,如下: define('RUNTIME_FILE','./App/temp/runtime_cache.php'); 我发现可以定义路径,但是文件名确没有如愿生成runtime_cache.php,始终是common~runtime.php。 我的修改如下: define('RUNTIME_PATH','./temp/');define('RUNTIME_FILE','./temp/runtime_cache.php'); 最后得到结果如下截图: 图3 这里面生成了一系列的目录和文件,都是和编译缓存相关的。下面来替换框架入口文件为这个缓存文件看看能否正常运行,修改代码如下: // 引入ThinkPHP入口文件require './temp/common~runtime.php';//require './ThinkPHP/ThinkPHP.php'; 结果出现了错误,代码如下: Fatal error: Class 'Think\Think' not found inD:\Serious\phpdev\thinkphp\temp\common~runtime.php on line 1 好吧,一开始只要知道有这么个东西就行了,不要玩这么高级的东西,先看看基本功能如何实现的吧。   2.调试模式 在项目入口文件中可以通过语句define('APP_DEBUG',True);来设置当前项目是否使用debug模式,待完成测试要部署到生产环境时再将这个值设置成False,就是部署模式。 使用调试模式给程序员带来以下便利: 错误信息会提交到日志记录中便于调试 关闭末班缓存,修改末班可以即时生效 记录sql日志,方便分析sql语句 关闭字段缓存,数据字段修改不受缓存影响 严格检查大小写,避免部署到linux上之后出现问题 上面很多特性都需要在配置文件中修改配置,下一篇文章中再做介绍。
文章
缓存  ·  PHP
2015-01-28
thinkphp学习笔记3—项目编译和调试模式
1.项目编译 在章节2.4项目编译中作者讲到使用thinkphp的项目在第一次运行的时候会吧核心需要加载的文件去掉空白和注释合并到一个文件中编译并缓存,第二次运行时直接载入编译缓存,这样省去一些IO开销,加快执行速度。并且在3.0以上的版本中海做了一些优化: 1.合并和兴编译缓存和项目编译缓存,不再生成两个缓存文件 2.直接对本地环境生成设置和常量定义减少环境判断 3.编译缓存可以直接替换框架入口甚至项目入口,甚至脱离框架独立运行 4.通过参数设置,生成的编译缓存载入外部的常量定义,便于产品用户定义 貌似高上大,后面继续讲在没有开启调试模式的情况下会在thinkphp\Application\Runtime目录下生成一个~runtime.php的文件,就是编译缓存文件。我实验了一下,在项目入口文件中有一句define('APP_DEBUG',True);修改成define('APP_DEBUG',False);,再次运行,在Runtime目录果然生成了一个类似文件,不过名称有点差别,是common~runtime.php,截图如下: 图1 打开这个common~runtime.php文件,我们可以看到内容是一行没有空格的代码,类似于压缩过的js代码,如下: 图2 注意环境改变之后这个缓存文件应该删除,不能把本地生成的编译缓存拷贝到其他服务器或者环境直接使用,只能再次生成。 编译缓存的内容包含:系统函数库,系统基础核心类库,扩展定义的核心行为类库,项目配置文件,项目函数文件。在项目入口文件中可以更改这个文件的生成目录例如: define('RUNTIME_PATH','./App/temp/'); 持此之外开可以弟子你故意缓存文件名,如下: define('RUNTIME_FILE','./App/temp/runtime_cache.php'); 我发现可以定义路径,但是文件名确没有如愿生成runtime_cache.php,始终是common~runtime.php。 我的修改如下: define('RUNTIME_PATH','./temp/');define('RUNTIME_FILE','./temp/runtime_cache.php'); 最后得到结果如下截图: 图3 这里面生成了一系列的目录和文件,都是和编译缓存相关的。下面来替换框架入口文件为这个缓存文件看看能否正常运行,修改代码如下: // 引入ThinkPHP入口文件require './temp/common~runtime.php';//require './ThinkPHP/ThinkPHP.php'; 结果出现了错误,代码如下: Fatal error: Class 'Think\Think' not found inD:\Serious\phpdev\thinkphp\temp\common~runtime.php on line 1 好吧,一开始只要知道有这么个东西就行了,不要玩这么高级的东西,先看看基本功能如何实现的吧。   2.调试模式 在项目入口文件中可以通过语句define('APP_DEBUG',True);来设置当前项目是否使用debug模式,待完成测试要部署到生产环境时再将这个值设置成False,就是部署模式。 使用调试模式给程序员带来以下便利: 错误信息会提交到日志记录中便于调试 关闭末班缓存,修改末班可以即时生效 记录sql日志,方便分析sql语句 关闭字段缓存,数据字段修改不受缓存影响 严格检查大小写,避免部署到linux上之后出现问题 上面很多特性都需要在配置文件中修改配置,下一篇文章中再做介绍。 作者:Tyler Ning 出处:http://www.cnblogs.com/tylerdonet/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com  联系我,非常感谢。
文章
缓存  ·  PHP
2014-06-14
网站读取不了数据了啊!:报错
很诡异的问题。 一切基于LINUX服务器重启之后,之前一切正常。 网站一篇空白,凡是从MYSQL读取的数据,都没有读取出来,仅有一些样式而已,没有任何数据显示出来。 代码、配置文件都没有修改过。 这时候有人就会说是服务器的问题吧? 但是:在这个服务器上另外一个网站(B网站),公用的一个MYSQL的网站,一切正常! 在PHPMYADMIN中执行select * from post,可以得到数据。 但是在A网站中,执行这句话,返回的是bool false! 数据库配置文件也没有任何问题!(因为根本没修改过,如果MYSQL信息填写错误,THINKPHP会报错!) A网站有一个OLD版本(之前同事写的), 和NEW版本(网站改版,新写的代码), A网站的2个版本,都读取不了数据! 但是B网站是正常的! 如果是服务器问题,为什么这个服务器上的另一个网站就正常呢? 如果是程序问题,为什么重启之前都是好的呢?
问答
关系型数据库  ·  MySQL  ·  Linux  ·  PHP  ·  数据库
2020-06-07
网站读取不了数据了啊!?报错
很诡异的问题。 一切基于LINUX服务器重启之后,之前一切正常。 网站一篇空白,凡是从MYSQL读取的数据,都没有读取出来,仅有一些样式而已,没有任何数据显示出来。 代码、配置文件都没有修改过。 这时候有人就会说是服务器的问题吧? 但是:在这个服务器上另外一个网站(B网站),公用的一个MYSQL的网站,一切正常! 在PHPMYADMIN中执行select * from post,可以得到数据。 但是在A网站中,执行这句话,返回的是bool false! 数据库配置文件也没有任何问题!(因为根本没修改过,如果MYSQL信息填写错误,THINKPHP会报错!) A网站有一个OLD版本(之前同事写的), 和NEW版本(网站改版,新写的代码), A网站的2个版本,都读取不了数据! 但是B网站是正常的! 如果是服务器问题,为什么这个服务器上的另一个网站就正常呢? 如果是程序问题,为什么重启之前都是好的呢?
问答
关系型数据库  ·  MySQL  ·  Linux  ·  PHP  ·  数据库
2020-06-22
html页面构造的多维数组在服务器端无法获取值
项目采用Thinkphp,前端框架用dwz,在页面构造了一个二维数组,如下: 短消息 邮件 微信 提交上去后,打印noticetype这个数组,得到的结果是:Array( [9353] => Array ( ['msg'] => msg ) [9784] => Array ( ['wechat'] => wechat ) [10113] => Array ( ['email'] => email ) ) 但是,当使用循环遍历上面这个数组,或者输出:"$_POST[noticetype][9784]['wechat"这种格式却显示空白,是不是post不该这样使用二维数组? 为什么能打印出完整的二维数组却无法获取单个值呢?
问答
前端开发  ·  PHP
2016-06-20
ThinkPHP框架学习(含数据库及I函数)
参考文献:https://www.kancloud.cn/manual/thinkphphttps://www.jianshu.com/p/ef3ee8260b2d www WEB子目录 ├─index.php 入口文件 ├─README.md README文件仅用于说明,实际部署的时候可以删除。 ├─Application 应用目录,默认是空的,但是第一次访问入口文件会自动生成 ├─Public 资源文件目录 └─ThinkPHP 框架目录 │ ├─Common 核心公共函数目录 │ ├─Conf 核心配置目录 │ ├─Lang 核心语言包目录 │ ├─Library 框架类库目录 │ │ ├─Think 核心Think类库包目录 │ │ ├─Behavior 行为类库目录 │ │ ├─Org Org类库包目录 │ │ ├─Vendor 第三方类库目录 │ │ ├─ ... 更多类库目录 │ ├─Mode 框架应用模式目录 │ ├─Tpl 系统模板目录 │ ├─LICENSE.txt 框架授权协议文件 │ ├─logo.png 框架LOGO文件 │ ├─README.txt 框架README文件 │ └─ThinkPHP.php 框架入口文件 入口文件(index.php) //定义应用入口文件 define('APP_PATH','./Application/'); require './ThinkPHP/ThinkPHP.php'; APP_PATH的定义支持相对路径和绝对路径,但必须以“/”结束 自动创建目录(第一次访问index.php): Application ├─Common 应用公共模块(不能直接访问) │ ├─Common 应用公共函数目录 │ └─Conf 应用公共配置文件目录 ├─Home 默认生成的Home模块 │ ├─Conf 模块配置文件目录 │ ├─Common 模块公共函数目录 │ ├─Controller 模块控制器目录 │ ├─Model 模块模型目录 │ └─View 模块视图文件目录 ├─Runtime 运行时目录 │ ├─Cache 模版缓存目录 │ ├─Data 数据目录 │ ├─Logs 日志目录 │ └─Temp 缓存目录 在自动生成目录结构的同时,在各个目录下面还生成了index.html文件,这是ThinkPHP自动生成的目录安全文件。为了避免某些服务器开启了目录浏览权限后可以直接在浏览器输入URL地址查看目录,系统默认开启了目录安全文件机制,会在自动生成目录的时候生成空白的index.html文件 控制器 在自动生成的Application/Home/Controller目录下面有一个 IndexController.class.php 文件,这就是默认的Index控制器文件。控制器类的命名方式是: 控制器名(驼峰法,首字母大写)+Controller 控制器文件的命名方式是:类名+class.php(类文件后缀) 命名规范 类文件都是以.class.php为后缀(这里是指的ThinkPHP内部使用的类库文件,不代表外部加载的类库文件),使用驼峰法命名,并且首字母大写,例如 DbMysql.class.php; 类的命名空间地址和所在的路径地址一致,例如Home\Controller\UserController类所在的路径应该是 Application/Home/Controller/UserController.class.php; 确保文件的命名和调用大小写一致,是由于在类Unix系统上面,对大小写是敏感的(而ThinkPHP在调试模式下面,即使在Windows平台也会严格检查大小写); 类名和文件名一致(包括上面说的大小写一致),例如 UserController类的文件命名是UserController.class.php, InfoModel类的文件名是InfoModel.class.php, 并且不同的类库的类命名有一定的规范; 函数、配置文件等其他类库文件之外的一般是以.php为后缀(第三方引入的不做要求); 函数的命名使用小写字母和下划线的方式,例如 get_client_ip; 方法的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 getUserName,_parseType,通常下划线开头的方法属于私有方法; 属性的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 tableName、_instance,通常下划线开头的属性属于私有属性; 以双下划线__打头的函数或方法作为魔法方法,例如 __call 和 __autoload; 常量以大写字母和下划线命名,例如 HAS_ONE和 MANY_TO_MANY; 配置参数以大写字母和下划线命名,例如HTML_CACHE_ON; 语言变量以大写字母和下划线命名,例如MY_LANG,以下划线打头的语言变量通常用于系统语言变量,例如 CLASS_NOT_EXIST; 对变量的命名没有强制的规范,可以根据团队规范来进行; ThinkPHP的模板文件默认是以.html 为后缀(可以通过配置修改); 数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例如 think_user 表和 user_name字段是正确写法,类似 _username 这样的数据表字段可能会被过滤。 配置加载 惯例配置->应用配置->模式配置->调试配置->状态配置->模块配置->扩展配置->动态配置//配置的优先顺序从右到左 框架内置有一个惯例配置文件(ThinkPHP/Conf/convention.php) 应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(Application/Common/Conf/config.php) 如果使用了普通应用模式之外的应用模式的话,还可以为应用模式单独定义配置文件,文件命名规范是: Application/Common/Conf/config_应用模式名称.php(仅在运行该模式下面才会加载)(可选) 开启调试模式,会自动加载框架的调试配置文件(ThinkPHP/Conf/debug.php)和应用调试配置文件(Application/Common/Conf/debug.php)(可选) 在公司和家里分别设置不同的数据库测试环境。在公司,在入口文件中定义:define('APP_STATUS','office');就会自动加载该状态对应的配置文件(Application/Common/Conf/office.php)。回家后,修改为:define('APP_STATUS','home');就会自动加载该状态对应的配置文件(Application/Common/Conf/home.php)。(可选) 读取配置 配置文件,统一使用系统提供的C方法来读取已有的配置。(ThinkPHP/Common/functions.php) 用法:C('参数名称') $model = C('URL_MODEL');//读取当前的URL模式配置参数 C('my_config',null,'default_config');//如果my_config尚未设置的话,则返回default_config字符串 因为配置参数是全局有效的,因此C方法可以在任何地方读取任何配置,即使某个设置参数已经生效过期了。 加载扩展配置 ①在Application/Home/Conf目录下新建user.php,内容如下 <?php return array( 'USER_TYPE' => 2, //用户类型 'USER_AUTH_ID' => 10, //用户认证ID 'USER_AUTH_TYPE' => 2, //用户认证模式 );//可以不用加?> ②修改同级的config.php <?php return array( 'LOAD_EXT_CONFIG'=> array('USER'=>'user') ); ③修改Application/Home/Controller/IndexController.class.php <?php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index(){ print_r(C('USER')); } } 打开localhost,会出现Array ( [USER_TYPE] => 2 [USER_AUTH_ID] => 10 [USER_AUTH_TYPE] => 2 ) 数据库操作分析 ①系统公共函数库: \ThinkPHP\Common\functions.php(封装了TP开放给外部的函数) ②ThinkPHP Model模型类: ThinkPHP\Library\Think\Model.class.php (TP的数据库架构类,提供curd类库,是一个对外的接口 ) ③TP内部curd类: ThinkPHP\Library\Think\Db\Driver.class.php (这个类的函数都被Model类中的curd操作间接的调用) Tp在执行数据库操作之前 函数M使用了以后会自动创建new Model类并且会实例化为一个对象返回此资源。 接着这个对象调用了where方法并且格式化处理以后,会将这个值赋值给此对象的一个成员变量$options(注:如果说我们在此对象中有调用其他的方法赋值例如where,table,alias,data,field,order,limit,page,group,having,join,union,distinct,lock,cache,comment等等这种操作方法,那么都会先赋值给此对象,而不是在代码直接进行sql语句拼接,所以我们使用Tp的连贯操作的时候,就不需要像SQL语句拼接那样需要考虑到关键字的顺序问题 处理完了前面选项之后,接下来就会去调用我们的find()方法去调用底层的一个select方法(Driver.class.php这个类中的select方法)来获取数据。所谓的find()方法就是等同于先给此对象的一个成员变量$options赋值操作limit=1然后进行select操作来获取对应的数据。 最终的sql语句:SELECT * FROMblog_adminWHERE username='admin' limit 1 如果给赋值了一个操作:M('admin')->field('username,password')->where( array('username'=>$username) )->find(); 执行的语句为SELECTusername,password FROMblog_adminWHERE username='admin' limit 1 ①thinkphp\ThinkPHP\Library\Think\Model.class.php 里的重要成员变量: protected $pk = 'id';// 主键名称 protected $fields = array(); // 字段信息 protected $options = array(); // 数据信息 protected $methods = array('strict','order','alias','having','group','lock','distinct','auto','filter','validate','result','token','index','force');// 链操作方法列表 ②where()方法的执行过程: $parse = array_map(array($this->db,'escapeString'),$parse);//对传递到字符串类型的数据,调用mysql_escape_string函数来处理任何返回 可以通过官方文档查看TP如何防止SQL注入:(http://document.thinkphp.cn/manual_3_2.html#sql_injection)where() 方法如果 传递的是$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx)) 这种格式的,就会进行 mysql 的mysql_escape_string函数进行处理(mysql_escape_string总是将“ ' ”转换成“ \ ”)。 处理完成以后就会将已处理完成的数组赋值到M对象的成员函数$this->options['where'](options为success,error,display.....) 随后返回,供我们进行下一步的处理。 ③find()方法的执行过程: $options = $this->_parseOptions($options);//分析表达式,获取执行的表的名称,获取模型的名称,最后对表的字段进行处理。 $resultSet = $this->db->select($options);//调用db对象里的select方法查询数据 此方法的功能就是 获取主键,完善model类的成员变量,options数组,然后实例化 db类,调用select 方法获取数据,然后处理数据完以后返回数据 Find方法使用的 $this->_parseOptions() 这个方法的主要就是 获取操作的表名,查看是否有取别名,获取操作的模型,比对当前表的数据库字段是否一致,若有不一致的字段 $this->options['strict'] 设置了的时侯,进行报错处理 否则进行删除多余字段的处理。 执行过滤的方法为_parseType ,功能是数据类型检测并且进行强制转换(强制转换的类型为int,float,bool 三种类型) Find方法使用的$this->db->select() 方法 $this->db 是在ThinkPHP\Library\Think\Db类中的方法 ①其中parseSql()这个函数的主要功能是拼接sql语句$this->parseWhere(!empty($options['where'])?$options['where']:''),parseWhere 方法比其他的要复杂的多,其他的都是拼接字符串,过滤,然后返回。) ②parseWhere()方法 这方法会去判断传进来的变量内容是否是字符串,如果是的话,就直接返回,如果不是字符串而是数组的话,那么就会挨个的解析,并且判断是否是特殊的条件表达式,如果是,调用parseThinkWhere()方法(主要是解析特殊的条件并且调用parseValue ()方法),已上条件都不匹配的情况下就认为是普通查询 普通查询都会调用parseWhereItem 方法 ③parseWhereItem()方法 protected function parseWhereItem($key,$val)//$val值是从where函数接收到的数据,然后经过这个方法会先去判断是否是数组,不是数组就会到下面的流程 ...... $exp = strtolower($val[0]);//$exp的值=执行表达式(可以操作sql拼接的流程)=$val[0] ······ elseif('bind' == $exp ){ // 使用表达式 $whereStr .= $key.' = :'.$val[1]; }elseif('exp' == $exp ){ // 使用表达式 $whereStr .= $key.' '.$val[1]; }elseif(preg_match('/^(notin|not in|in)$/',$exp)){ // IN 运算 if(isset($val[2]) && 'exp'==$val[2]) { $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1];//这三句 $whereStr .没有使用TP的过滤。 进入此方法以后会发现这个方法会根据 $exp 变量的不同 拼接不同的sql语句 而在这个方法中看到最多的就是parseValue()方法了 ④parseValue ()方法 这个方法会去调用escapeString()方法 (将传进来的变量进行addslashes 然后返回) 嗯。。。。。。。整体流程看起来我们可以发现TP使用的过滤方法就是一个简单addslashes 来防止过滤 I 函数(官方http://document.thinkphp.cn/manual_3_2.html#input_filter) 路径:ThinkPHP\Common\functions.php 方法名:function I($name,$default='',$filter=null,$datas=null)主要功能 确定数据类型 对数据进行循环取值 调用think_filter 函数进行过滤 在think_filter中: if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ $value .= ' ';//正则匹配,过滤查询特殊字符,然后在这些条件表达式后面添加一个空格 例如: 没有使用think_filter 函数时: goods_name[0]=in&goods_name[1]=(true) and (updatexml(1,concat(1,(select user())),1))--&goods_name[2]=exp 使用了think_filter函数时: goods_name[0]=in &goods_name[1]=(true) and (updatexml(1,concat(1,(select user())),1))--&goods_name[2]=exp 其中elseif(preg_match('/^(notin|not in|in)$/',$exp))中If( in(空格) == 'in')不匹配,也就防止了sql注入的产生 审计方式 ①进入目录直接搜索 $_POST $_GET 查看是否带入了 where 查询。 ② 全局搜索 where 查看是否有字符串拼接的痕迹 ③全局搜索 order,having,group,alias (例:当我们可以操控 order传进去的参数时,也是可以进行注入的,这是因为tp对order方法只是一个字符串拼接的操作 ) ④全局搜索 join ,field,执行的都是字符串拼接,只要可以外部操作就可以产生注入
文章
SQL  ·  PHP  ·  数据库  ·  安全  ·  缓存  ·  .NET  ·  开发框架  ·  测试技术  ·  关系型数据库  ·  MySQL
2018-04-23
阿里云云虚拟主机使用常见问题汇总
产品计费问题计费常见问题网站无法访问网站无法访问的常见问题及解决方法访问网站不能正常显示图片或显示不完整的原因访问网站提示“该页面暂时无法访问”访问网站出现乱码的现象访问网站时出现“温馨提示:该网站暂时无法访问”访问网站提示“抱歉!该网站可能由于以下原因无法访问”访问网站提示“无法显示页面,因为发生内部程序错误”访问网站提示“无法添加类型为‘add’的重复集合项”访问网站时出现MP4格式的视频无法播放访问网站时提示该网站为空壳网站域名或网站无法访问的原因及解决方法云虚拟主机被黑客入侵导致网站无法访问的处理方法共享云虚拟主机网站流量超标导致网站无法访问云虚拟主机升级后网站无法访问的解决方法网站访问报错访问网站常见报错访问网站提示“Internal Server Error”报错访问网站出现“ You don't have permission to access xxxx on this server”报错访问网站提示“HTTP 错误 404.3 - Not Found”报错访问网站出现"HTTP 错误 500.19 - Internal Server Error"报错访问网站提示“Warning: chmod() has been disabled for security reasons”报错访问网站出现“max_user_connections”报错访问网站出现“Class ‘ZipArchive’ not found”报错访问网站提示“warning:session_start()”报错访问网站提示“非常抱歉”错误访问云虚拟主机中搭建的网站时提示“该网站因主机过期暂时无法访问”访问网站时报错:403 Forbidden访问网站404页面时出现301报错访问网站提示数据库连接失败访问Discuz!网站时自动跳转至其他页面修改数据库密码后无法访问Discuz!论坛重置数据库密码后导致网站无法访问网站响应异常访问云虚拟主机站点显示文件名访问子目录出现403报错访问ASP页面提示错误访问Windows站点提示“HTTP 错误 500.22 - Internal Server Error”访问Windows站点提示“HTTP 错误 500.0 - Internal Server Error”访问Windows站点提示“An error occurred on the server when processing the URL”访问Discuz论坛提示“Discuz! Database Error”修改WordPress站点主题提示报错访问WordPress页面提示“Cannot modify header information - headers already sent”在IE浏览器中访问Linux系统网站页面出现排版问题网站访问缓慢访问网站速度较慢的排查方法网站图片过多导致网页访问慢网站访问缓慢访问网站存在间歇性无法访问的情况网站管理常见问题基于.NET Framework环境的网站运行速度变慢PHP网站访问异常访问PHP网站为空白页面PHP站点显示异常访问PHP程序页面出现"Warning: Cannot modify header information - headers already sent by …."报错PHP网站运行提示“PHP Fatal error”PHP站点提示“Fatal error:Incompatible file format”报错ThinkPHP站点提示“class not found Runtime/~runtime.php”使用PHP安装Discuz论坛提示“mysqlnd cannot connect to MySQL 4.1+ using the old insecure”FTP连接异常使用FTP的注意事项FTP客户端向云虚拟主机发送“AUTH TLS”后出现“无法连接到服务器”提示使用FTP客户端连接站点时报错:227 Entering Passive Mode使用FTP客户端连接云虚拟主机时提示“530 Login incorrect”错误使用FileZilla连接云虚拟主机提示“421 There are too many connections from your internet address.”错误使用FileZilla连接站点时出现乱码使用FileZilla连接云虚拟主机报错FTP使用异常通过FTP软件创建目录时出现“550 Create Directory Operation Failed”报错Linux系统云虚拟主机通过网站后台上传文件异常上传文件后文件大小变成0 KBLinux系统的云虚拟主机无法删除目录或文件Linux系统的云虚拟主机无法通过FTP删除目录将网站程序上传至轻云服务器和云虚拟主机提示“Fatal error: Unable to read XXXX bytes”因编码问题无法上传文件创建文件夹时报错:550 Create directory operation failed创建文件时报错:553 could not create file使用FTP下载文件时出现中断脚本文件上传后无法执行文件上传后的最近修改时间显示错误通过FTP客户端向云虚拟主机上传文件时出现异常的解决方法使用FTP客户端传输文件到云虚拟主机速度慢的解决方法网站迁移异常ThinkPHP程序迁移后访问站点是空白页面WordPress站点迁移至云虚拟主机后提示“存在循环重定向”迁移.NET程序至Windows云虚拟主机时出现加密报错执行数据库搬家操作时导入SQL Server备份文件失败控制面板问题云虚拟主机网站日志分析方法主机管理控制台中主机域名解析状态显示失败访问云虚拟主机统计报告页面显示乱码M2型云虚拟主机无法在控制面板中添加支持MP4格式文件的设置屏蔽指定IP地址的方法登录主机控制台出现“获取站点空间使用情况失败”报错使用Discuz云平台诊断工具出现报错数据库问题MySQL数据库变更为高版本后无法导入原低版本数据云虚拟主机过期后备份数据库数据云虚拟机的MySQL数据库修改max_allowed_packet值访问网站后台出现“可能数据库密码不对或数据库服务器出错!”云虚拟主机数据库中文乱码云虚拟主机中MySQL数据库出现“Too many connections”报错PHP程序调用SQL Server数据库提示“Call to undefined function sqlsrv_connect()”Linux操作系统云虚拟主机数据库常见问题Windows云虚拟主机数据库常见问题云虚拟主机MySQL数据库是否支持开启event_scheduler使用企业管理器导入SQL Server数据失败通过DMS导入SQL文件失败还原SQL Server 2008数据库失败网站程序调用数据库失败导入SQL文件时报错:unknown collation utf8mb4_unicode_ci使用phpMyAdmin连接数据库失败误删除云虚拟主机的MySQL数据库连接云虚拟主机的MySQL数据库失败主机功能问题云虚拟主机设置Gzip压缩功能不生效云虚拟主机.NET程序生成Microsoft office文件时报错修改翔云主机和锋云主机密码提示“操作失败,请联系万网客服”云虚拟主机内DedeCMS程序采集功能未生效更新云虚拟主机站点的emlog模板提示“模板下载失败”管理控制台常见问题云虚拟主机默认首页不生效自定义404错误页面未生效主机控制台文件管理功能中不显示htdocs目录网站程序自动创建的目录没有写权限云虚拟主机无法删除文件压缩文件失败解压缩文件失败流量统计报告中出现乱码通过URL无法下载APK文件主机功能设置方法如何在虚拟主机中设置301重定向如何在云虚拟主机中开启PHP的Register Globals功能云虚拟主机内安装Discuz论坛后如何使用邮箱功能通过探针查看云虚拟主机支持的PHP版本及相关配置云虚拟主机更换系统后如何设置域名解析域名解析到多个IP导致部分地区网站无法打开第三方浏览器访问虚拟主机临时域名出现样式错误问题如何恢复备份的云虚拟主机网站数据和数据库数据如何下载网站的访问日志云虚拟主机开启HTTPS加密访问不生效主机耗资源/DDoS/大流量问题常见的网络攻击类型及其排查处理建议云虚拟主机木马查杀服务介绍及常见问题防止黑客攻击云虚拟主机的网站共享型云虚拟主机收到被DDoS攻击关停邮件时的处理方法网站耗资源的原因及解决方法云虚拟主机被爬虫访问耗费大量流量的解决方法耗资源(客户程序故障)常见问题共享云虚拟主机流量常见问题安装问题安装完WordPress程序后访问跳转到虚拟主机临时域名云虚拟主机安装WordPress忘记后台管理员密码如何处理安装DedeCMS程序后无法访问云虚拟主机中安装ShopNC常见问题云虚拟主机内安装Discuz论坛提示不支持fsockopen函数在云虚拟主机中安装Joomla时提示不支持魔术引号安装程序时提示目录不可写云虚拟主机更换系统后访问ThinkPHP站点提示“模板不存在”
文章
SQL  ·  域名解析  ·  安全  ·  关系型数据库  ·  MySQL  ·  Linux  ·  PHP  ·  数据库  ·  数据安全/隐私保护  ·  Windows
2021-10-09
将ThinkPHP和UCenter整合
最近应公司的要求,要开发一个有点像QQ空间那样的会员管理中心网站,发现UCenter的很多功能酷似QQ空间,于是选择了UCenter作为程序的会员管理中心。前台嘛就选择我之前基于ThinkPHP3.1.2框架开发的WBlog好了。但是问题又来了:要求在WBlog前台注册的会员登录时要与UCenter同步,这就是我这次要解决的问题--ThinkPHP与UCenter的整合。我在网上搜索了一下,ThinkPHP与UCenter的整合并不少,但是似乎越看越觉得头晕,不是少这就是少那,到头来差之毫厘,谬以千里,真够折腾的。我仔细阅读了UCenter的开发文档后,经过多次的调试,终于完成了ThinkPHP与UCenter的整合。感觉这个结果是从苦水里泡出来的一样,呵呵。。。现在把整合的记录分享给需要的童鞋。温馨提示:在thinphp与UCenter整合中,您需要的基本条件是,有一定的PHP基础,对ThinkPHP框架有所了解,会布署目录和配置数据。好了,我们开始吧!下载并安装下面的程序WBlog3.1.2UCenter_Home_2.0_SC_UTF8UCenter 1.6.0安装WBlog博客程序已发布的WBlog博客程序还没有会员中心,本次测试的会员中心是后面才写的。如果你能等的话要待我整理好WBlog的会员中心程序才发布,不能等的话也不会影响下面的程序整合,因为你可以找或者自己写简单的满足以下两个条件的thikphp程序:1、可以注册会员2、可以登录和退出。这里我就使用WBlog3.1.2了。在服务器的根目录新建目录wblog1,把下载的WBlog3.1.2解压得到的WBlog目录里的所有文件复制到wblog1。在浏览器输入http://127.0.0.1/wblog1/install/,安装WBlog3.1.2。温馨提示:在整合时最容易搞错的就是路径问题,在接下来的整合操作的根目录都是指wblog1目录,所以要和服务器根目录区别开来。安装UCenter 1.6.0(简体UTF-8)这个程序到官方去下载吧。在网站根目录wblog1新建 ucenter 目录,解压UCenter 1.6.0,把解压得到的upload目录里的所有文件复制到刚才新建的ucenter目录里。在浏览器输入http://127.0.0.1/wblog1/ucenter/install/,安装UCenter 1.6.0。安装UCenter_Home_2.0_SC_UTF8(简体中文版)在网站根目录wblog1新建 uh目录并解压UCenter_Home_2.0_SC_UTF8,把解压得到的upload目录里的所有文件复制到刚才新建的uh目录里。在浏览器输入http://127.0.0.1/wblog1/uh/install/,安装UCenter_Home_2.0_SC_UTF8。需要注意的是,安装UCenter 1.6.0和UCenter_Home_2.0_SC_UTF8时顺序不能颠倒,否则无法安装。我们安装完了WBlog3.1.2、UCenter_Home_2.0_SC_UTF8和UCenter 1.6.0三个程序后。接下来找到下载的UCenter 1.6.0,把 advanced 目录里面的uc_client 和 examples下面的api 文件夹复制到网站根目录wblog1下,和ThinkPHP在同一目录。找到项目W3note的配置文件夹wblog1/ Conf/,在其新建一个UCenter的配置文件 config_ucenter.php ,然后在WBlog1\W3note\Lib\ORG目录下新建一个UCenter的通讯处理类文件UcService.class.php,我们先不要管文件里面写什么代码,后面将会讲到。好了到这里已经把后面要操作的目录和文件都布局好了。为了理清目录和文件之间的层次关系,我把目录和文件制成目录树列出来:wblog1根目录| – index.php//前台入口文件| – admin.php| – W3note//前台项目| | – Lib| | | – ORG| | | | –UcService.class.php //UCenter的通讯处理类文件| | – Conf//W3note项目的配置目录| | | –config_ucenter.php //UCenter的配置文件| || – Admin| – ThinkPHP //thinkphp3.1.2核心包和一些扩展| – install| – api| | – uc.php|| – uc_client| – ucenter| – uh这样我们就可以一目了然了。现在开始api目录里面的uc.php 配置了,首先打开这个文件,找到36行的位置这一行代码 1 require_once DISCUZ_ROOT.'./config.inc.php'; 把'./config.inc.php'这一部分替换成'./W3note/Conf/config_ucenter.php'往下找还会看到几处的'./config.inc.php',按照上面的操作全部替换掉。这样做目的是把前面建的配置文件config_ucenter.php导进来。 接下来我登录http://127.0.0.1/wblog1/ucenter,在打开左边菜单“应用管理”这一项,然后添加一个新应用,这时我们发现好多东西要填!照着下面操作就是了。先看应用类型,因为这是我们自己开发的程序,所以就选其它吧,再看应用名称,随便填,只要不超过20字节就行了,我这里填wblog。接下来是应用的主URL,这里填网站的主页http;//127.0.0.1/wblog1,注意了,后面没有“/”。至于应用的其他URL还有应用IP这两项就跳过,不用管它了。接下来是通信密钥,就按其旁边的提示填就是了,我这里填abc123456。往下是应用的物路径,提示说默认为空,那就留空吧,还有查看个人资料页面地址也留空吧。接下来是应用接口文件名称,默认为uc.php,保持原状吧。继续往下看,标签单条显示模板还有标签模板标记说明这两项也不用理它,跳过。是否开启同步登录,选是;是否接受通知也选是吧。终于填完了,那就点击提交吧!还记得前面在uc.php导入的文件config_ucenter.php吗,里面可是一片空白啊,现在我们就来放些配置信息进去。刚才我们填好的信息提交后,会在提交按钮下面的“应用的UCenter配置信息”下面生成了一些配置信息,我们直接把它复制,然后粘帖到config_ucenter.php,保存。网上很多教程到这里就表示通信成功了,在这里我非常惊讶!因为通信并未成功!我在这里折腾了一些时间,后来仔细检了uc.php文件的代码,发现59行: 1 require_once DISCUZ_ROOT.'./include/db_mysql.class.php'; 我在布局的目录中始终找不到db_mysql.class.php,后来发现db_mysql.class.php存UCenter_1.6.0_SC_UTF8\advanced\examples\include目录中,这就是问题所在!因为我们之前复制的只是UCenter_1.6.0_SC_UTF8\advanced\examples\中的api文件。解决这一问题的办法就是把上面的代码修改为 1 require_once DISCUZ_ROOT.'./uc_client/lib/db.class.php'; 导入的数据库类文件变了,那么我们也要对其所涉及的内容作相应的修改,在uc.php59行的下面如 1 2 3 4 5 6 7 $GLOBALS['db'] = new dbstuff; $GLOBALS['db']->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, true, $dbcharset); $GLOBALS['tablepre'] = $tablepre; 修改为 $GLOBALS['db'] = new ucclient_db; $GLOBALS['db']->connect(UC_DBHOST, UC_DBUSER, UC_DBPW, UC_DBNAME, UC_DBCONNECT, true, UC_DBCHARSET); $GLOBALS['tablepre'] = UC_DBTABLEPRE;//关键 上面数据库的链接信息的静态变量来自config_ucenter.php。好了,我们回到后台ucenter刷新一下页面,发现什么---通信成功了!那么接下来我们的目标:在thinkphp中会员注册成功时,UCenter Home也同时注册成功。首先在项目W3note入口文件index.php配置一个常量define('WBLOG_ROOT_PATH', rtrim(dirname(__FILE__), '/\\') . DIRECTORY_SEPARATOR);//物理根目录常量WBLOG_ROOT_PATH是网站根目录wblog1的物理根目录,在我本地服务器打印输出:D:\phpsever\apache2\htdocs\wblog1\有必要在这里强调一下,理解WBLOG_ROOT_PATH很重要,因为在调试过程中路径最容易出错。还记得前面我们建的UcService.class.php 文件吗?如果忘记了请看一下前面的目录树。打开UcService.class.php文件,新建一个类UcService,然后写一个构造方法导入W3note/Conf/config_ucenter.php和uc_client/client.php两个文件。代码: 1 2 3 4 5 class UcService{ public function __construct(){ include_once(WBLOG_ROOT_PATH . 'W3note/Conf/config_ucenter.php'); include_once(WBLOG_ROOT_PATH . 'uc_client/client.php'); } 接下来我们写一个会员注册方法register,如public function register($username, $password, $email){}方法体放什么代码呢?其实很简单,因为UCenter的开发文档已经为我们准备好了!找到之前下载的UCenter_1.6.0_SC_UTF8,用浏览器打开UCenter_1.6.0_SC_UTF\advanced\document\index.htm,然后在左边的菜单栏找到“用户接口”,看到用户注册示例 (PHP),把其下的代码复制过来。如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 /** * 会员注册 */ public function register($username, $password, $email){ $uid = uc_user_register($username, $password, $email);//UCenter的注册验证函数 if($uid <= 0) { if($uid == -1) { return '用户名不合法'; } elseif($uid == -2) { return '包含不允许注册的词语'; } elseif($uid == -3) { return '用户名已经存在'; } elseif($uid == -4) { return 'Email 格式有误'; } elseif($uid == -5) { return 'Email 不允许注册'; } elseif($uid == -6) { return '该 Email 已经被注册'; } else { return '未定义'; } } else { return intval($uid);//返回一个非负数 } } } 这个注册方法register的作用是,在wblog1的会员注册中成功注册一个会员时,也会成功注册UCenter Home的会员中心中。UCenter的注册方法我们在上面已经写好了,现在回到thinkphp。我们在前台W3note项目的控制器MemberAction写一个注册方法,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /* 用户名:$username, 密码:$password, 邮箱:$email */ public function addmember(){ if($this->isPost()){ $username = $_POST['username']; $email = $_POST['email']; $password = trim($_POST['password']); import("@.ORG.UcService");//导入UcService.class.php类 $ucService = new UcService;//实例化UcService类 $uid = $ucService->register($username, $password, $email);//注册到UCenter if($uid){//如果上面注册成功将返回一个int类型的数字 $M = D('Member'); if ($vo = $M->create()) { if ($M->add()) { $this->success('注册成功!'); } else { $this->error('注册失败!'); } } else { $this->error(); } }else{ exit($uid); } }else{ $this->error('非法数据!'); } } 1 2 3 我们在thinkphp会员注册页面注册一个帐号,提交表单后,查看wblog1和UCenter的会员数据表,发现两张表都存相同的帐号,说明同步注册已经成功了! 有了帐号我们就可以来做同步登录了。 打开UcService.class.php文件,添加一个UC登录和一个登出的方法,代码到UCenter接口开发手册的用户接口那里找用户登录示例代码,把它复制过来,然后稍微更改一下,使其带有返回值,以便下一步的操作,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public function uc_login($username, $password){ list($uid, $username, $password, $email) = uc_user_login($username, $password); if($uid > 0) { return array( 'uid' => $uid, 'username' => $username, 'password' => $password, 'email' => $email ); } elseif($uid == -1) { return '用户不存在,或者被删除'; } elseif($uid == -2) { return '密码错误'; } elseif($uid == -3) { return '安全提问错误'; } else { return '未定义'; } } 继续在用户接口那里找到同步登录的代码示例,找到“uc_user_synlogin($uid);”其作用是执行同步登录,然后写成uc_synlogin方法如下: 1 2 3 public function uc_synlogin($uid){ return uc_user_synlogin($uid); } 到这里UcService.class.php文件的登录方法已经写好,接下来打开前台W3note项目的控制器MemberAction.class.php文件写一个同步登录的方法,看代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public function checkLogin() { if(!$_POST['username']) $this->error('帐号错误!'); if(!$_POST['password']) $this->error('密码错误!'); if(empty($_POST['verify'])) $this->error('验证码必须!'); import("@.ORG.UcService");//导入UcService.class.php类 $ucService = new UcService; $uidarray = $ucService->uc_login($_POST['username'], $_POST['password']); //dump($uidarray); $loginurl=$ucService->uc_synlogin($uidarray); echo $loginurl;//输出同步登录代码,否则无法同步登录 if(!is_string($uidarray)){ //生成认证条件 $map = array(); // 支持使用绑定帐号登录 $map['username'] = $_POST['username']; $map["status"] = array('gt',0); if($_SESSION['verify'] != md5($_POST['verify'])) { $this->error('验证码错误!'); } $memberinfo=$this->Member->where($map)->find(); if(false === $memberinfo) { $this->error('帐号不存在或已禁用!'); }elseif($memberinfo['status']==0){ $this->error('帐号已禁用!'); }else { $password = pwdHash($_POST['password']); if($memberinfo['password'] != $password) { $this->error('密码错误!'); } session(C('USER_AUTH_KEY'), $memberinfo['id']); session('email', $memberinfo['email'] ); session('loginUserName', $memberinfo['loginUserName']); session('lastLoginTime', $memberinfo['lastLoginTime']); session('loginnum', $memberinfo['loginnum']); session('lastloginip', $memberinfo['lastloginip']); //保存登录信息(相当于更新信息) $data = array(); $data['id'] = $memberinfo['id']; $data['lastlogintime'] = time(); $data['loginnum'] = array('exp','loginnum+1'); $data['lastloginip'] = get_client_ip(); //$data['verify'] = $authInfo['verify']; $this->Member->save($data); $this->success('登录成功!',U('Member/index')); } } } 我们来看一下checkLogin()方法的执行过程。在项目W3note注册的一个帐号,然后在项目W3note提交登录表单后,首先执行UCenter的登录,前面我们写了两个UCenter的登录方法,在调用之前需要使用“import("@.ORG.UcService");”把UcService.class.php文件加载进来,实例化后得到$ucService,然后就可以使用用$ucService访问UCenterr的登录方法uc_login,返回一个$uidarray值,$uidarray包函什么数据?使用“dump($uidarray);”打印出来,以便下一步的操作,打印结果如下: 1 2 3 4 5 6 array(4) { ["uid"] => string(1) "1" ["username"] => string(5) "qqabc" ["password"] => string(6) "123456" ["email"] => string(9) "qq@qq.com" } 下一步就是以此$uidarray作为参数传给同步登录方法uc_synlogin($uidarray),最后echo 一下uc_synlogin($uidarray)的返回值$loginurl,就可以实现帐号"qqabc"在UCenter登录了。帐号"qqabc"在UCenter登录成功后程序将继续往下执行项目W3note的登录,这里就不多说了。最后的结果是,帐号"qqabc"实现了在UCenter和项目W3note的同步登录! 本文转自 3147972 51CTO博客,原文链接:http://blog.51cto.com/a3147972/1229781,如需转载请自行联系原作者
文章
API  ·  PHP  ·  数据安全/隐私保护
2017-11-24
跳转至:
阿里云内容服务
2 人关注 | 13 讨论 | 2 内容
+ 订阅
  • 阿里云云虚拟主机使用常见问题汇总
  • OSS常见问题
查看更多 >
开发与运维
5252 人关注 | 125986 讨论 | 203859 内容
+ 订阅
  • 假期借助阿里云ECS搭建一个个人游戏服务器
  • ECS使用体验
  • 云上linux实战 搭建游戏服务器
查看更多 >
数据库
249371 人关注 | 44651 讨论 | 63058 内容
+ 订阅
  • Redis 常见经典面试题
  • ECS使用体验
  • 高校学生ECS试用体验与感想分享
查看更多 >
安全
1063 人关注 | 23293 讨论 | 56571 内容
+ 订阅
  • Redis 常见经典面试题
  • 假期借助阿里云ECS搭建一个个人游戏服务器
  • 云上linux实战 搭建游戏服务器
查看更多 >
云计算
21620 人关注 | 57927 讨论 | 39470 内容
+ 订阅
  • Redis 常见经典面试题
  • 假期借助阿里云ECS搭建一个个人游戏服务器
  • ECS使用体验
查看更多 >