分类目录归档:PHP_Mysql

php 操作数组 add_assoc_string 导致 崩溃

使用php内核的方法 操作数组时 导致 php崩溃。

int add_assoc_string ( zval* $arg, char* $key, char* $str, int $duplicate )*

http://php.undmedlibrary.org/manual/en/zend-api.add-assoc-string.php

原因是:第三个参数, 添加的字符串不能使NULL。

添加之前要先判。 如果是NULL, 应该使用专门加NULL的api:

int add_assoc_null ( zval* $arg, char* $key )

http://php.undmedlibrary.org/manual/en/zend-api.add-assoc-null.php

byNeil
byNeil.com

原文来自 Blog by Neil, post php 操作数组 add_assoc_string 导致 崩溃 转载请注明出处。本站保留一切权力

mysql免密码登录, 及使用-e 参数执行sql脚本

我们在编写shell脚本的时候,经常需要和 mysql 交互.

如果是交互环境,可能使用这样的命令登录到mysql

#mysql –uroot –p

然后按提示输入密码, 登录. 如果在脚本中, 我们就不得不把密码写在 –p 参数后面. 这样 很容易暴露密码.

幸好mysql提供的有解决方案. 在 “~/.my.cnf” 文件中保存密码就行了.

MySQL官方文档

文件内容大概如下:

[client]

password="MySQL密码"

user=MySQL用户名

其中user 行可以省略, 默认使用当前的用户名填充mysql的登录用户名

再次使用 mysql 命令的时候,就无需输入用户名和密码了,可以自动登录.

还可以给 mysql 命令使用 --defaults-file 参数来指定特定的配置文件路径:

mysql --defaults-file=/folder1/folder2/filename -u 用户名

实现了免密码登录之后, 在脚本中就可以直接使用 -e 参数来执行sql脚本了, 而不用像交互式一样登录到mysql之后执行了.

mysql -e "CREATE DATABASE test" 

到这里, 基本上就可以实现完全的无值守 mysql脚本操作了.

参考: http://yzs.me/2142.html

byNeil
byNeil.com

原文来自 Blog by Neil, post mysql免密码登录, 及使用-e 参数执行sql脚本 转载请注明出处。本站保留一切权力

密码太长导致mysql:ERROR] Slave I/O: error connecting to master ‘replication@******:3306’ – retry-time: 60 retries: 2, Error_code: 1045

配置mysql主从备份,遇到在从服务器上slave启动不成功。

查看错误日志,

ERROR] Slave I/O: error connecting to master 'replication@*****:3306' - retry-time: 60  retries: 2, Error_code: 1045

 

第一想法是密码错误了。  于是先停止slave,重设master。

stop slave;

CHANGE MASTER TO MASTER_HOST='108.***.***.***',
MASTER_USER='repl_user2',
MASTER_PASSWORD='hfn98kMnsdfposdfasdfsadfsdjntuyuzcndfasdfsfsdfdsfsdfsdfsdf',

MASTER_LOG_FILE='mysql-bin.000008',
MASTER_LOG_POS=107;

然后重启 slave:

start slave;

 

之后发现还是:

Slave_IO_Running: NO

 

网上搜了很多, 说这个1045错误代码就是密码不对。如此重试了几次,确保密码复制粘贴没错。

手动用远程登录也没有问题,证明用户名和密码都没错。

 

查看日志,也没有详细信息。

在mysql的data目录下游荡,希望有什么有用的信息:

 

image

 

我们知道 master.info 记录的刚才设置的master信息的。 实在没有别的思路了,看看master.info 吧。

image

 

可以看到,里面记录了刚才设的master信息。

 

一眼看过去觉得有点不对。

哪里不对?  发现这里记录的密码长度变短了。

 

我再前面change master语句中给出的密码是很长的:

hfn98kMnsdfposdfasdfsadfsdjntuyuzcndfasdfsfsdfdsfsdfsdfsdf

但是这里记录的密码只有前面一段:

hfn98kMnsdfposdfasdfsadfsdjntuyuzcn

 

可以发现, 密码被截断了。

 

我知道了。应该是问题在这。于是去主服务器把密码改短。 再回来试试。

果然就成功了。

 

不知道为什么会被截断,但是希望能帮到你。 有知道的希望指点一下。

blog.byneil.com
byNeil
byNeil.com

解决:wordpress无法安装插件,无法安装主题

为了提高本博客的访问速度, 前几天更换了vps, 于是昨天把博客搬家到新的vps上了。

一切看起来还不错。登录后台时发现后台清净了很多。

 

image

也没注意。

今天尝试安装另外一个插件时除了问题。 后台搜索插件:

wordpress无法安装插件,无法安装主题

 

image

第一反应是,文件夹权限不对。

于是, 后台去 chown, chgrp

 

一对权限加到最大。

 

最后发现,新站点php运行在安全模式下, 想到可能是安全模式权限不够, 于是关闭安全模式,问题解决了。

 

这个插件可在后台直接更改 safemode。

不用去修改php配置。

 

http://wordpress.org/plugins/safe-mode/

byNeil
byNeil.com

原文来自 Blog by Neil, post 解决:wordpress无法安装插件,无法安装主题 转载请注明出处。本站保留一切权力

Thinkphp独立分组模式下,每个分组的单独配置文件config.php位置在哪里

我使用的是Thinkphp 3.1.3,  也就是今天的3.1最新版本。 其实官方3.2已经正式发布了, 看了一下,改变比较多,而且不兼容,所以暂时先不升级了。

我配置了三个独立分组:

'APP_GROUP_LIST'=>'Home,Admin,SN',
 'DEFAULT_GROUP'=>'Home',
 'APP_GROUP_MODE'=>1,

我需要对其中一个分组使用单独的config.php

按照官方的文档:http://doc.thinkphp.cn/manual/group_config.html

--------------------------------------------------------------------------------------------------------------------


如果启用了模块分组,则可以在对每个分组单独定义配置文件,分组配置文件位于:
项目配置目录/分组名称/config.php
可以通过如下配置启用分组:
  1. 'APP_GROUP_LIST' => 'Home,Admin', //项目分组设定
  2.  'DEFAULT_GROUP'  => 'Home', //默认分组
现在定义了Home和Admin两个分组,则我们可以定义分组配置文件如下:
Conf/Home/config.php
Conf/Admin/config.php
每个分组的配置文件仅在当前分组有效,分组配置的定义格式和项目配置是一样的。

 

-----------------------------------------------------------------------------------------------------------------

但是,不知道为什么就是不起作用,这问题困扰了我很久。 网上找到的所有答案都是从官方文档拷的,所以也一样。幸好Thinkphp是开源的。没办法,咱只有读代码了。

在Thinkphp/LIb/Core/Dispatcher.class.php 中找到 dispatch() 函数, 再找到大概 163 行,有个注释:

// 加载分组配置文件
 if(is_file($config_path.'config.php'))
     C(include $config_path.'config.php');

这里就是在加载分组的独立配置文件了。

再倒回去10行左右, 找到 "$config_path" 的定义:

// 定义项目基础加载路径
define('BASE_LIB_PATH', (defined('GROUP_NAME') && C('APP_GROUP_MODE')==1) ? APP_PATH.C('APP_GROUP_PATH').'/'.GROUP_NAME.'/' : LIB_PATH);

结合这两个定义,可以知道,官方的文档说的是错的。  独立分组的配置文件正确的位置在:(以Admin分组为例)

Admin/Config/config.php

这个Admin就是你的分组目录, 不是在Config目录下新建的Admin目录。 全路径看起来应该是这样的:

/app/Modules/Admin/Config/config.php

打完收工。
byNeil
byNeil.com

原文来自 Blog by Neil, post Thinkphp独立分组模式下,每个分组的单独配置文件config.php位置在哪里 转载请注明出处。本站保留一切权力

记一次艰苦卓绝的Discuz x3 论坛升级过程

首先吐槽一下discuz 的官方论坛. 你要想下载到正确版本的discuz实在不容易找到. 有兴趣自己去看吧. 就是因为这个原因, 我本来想要安装x2.5版本(那时x3 还是Beta版本), 结果不小心下载成了x2.  也就是不久前, x3才发布正式版.   我最近想要安装几个插件,和皮肤, 但是打开插件中心, 发现我所有的插件都安装不了, 说我的版本不支持.

我确信是x2.5 的插件, 语言版本也没问题(我一直以为自己的论坛是x2.5), 这就奇怪了. 我也觉得discuz不会有这么明显的bug啊.网上搜了很多,都说是版本不对, 请仔细核对版本. 这问题一直困然了我很久.  当时没有紧急的需求,也就放下了.

直到今天, 我想安装插件和皮肤, 我决定把这个安装不了插件的问题搞定. 最终还是要核对版本, 我突然想到好像在别人的论坛下面看到过 类似 "x2.5" 的版权申明(就是在论坛首页的下面声明的).  再看看我自己的是 "x2", 所以我猜测可能是我的版本安装错了.  所以本地搭建php环境(wamp server), 去discuz官方仔细找到2.5的下载地址. 本地安装.  证实我的猜测是对的. 我的论坛装错了.  现在查件中心绝大部分插件和皮肤都只支持2.5和3, 所以要想装查件, 只能升级了.

我的论坛已经有很多用户和数据了, 不能重装, 现在只能选择升级了. 好吧, 要升就直接升到最新x3吧.  好在官方的升级脚本还是比较详细的, 而且我也相信discuz的实力, 官方说支持从x2直接升到x3.

为了确保万无一失, 我先把服务器上的文件和数据库都备份到本地的php环境. 在本地"预升级"一次.  按照官方给的步骤,很简单就完成了.  打开页面看了一下,也没有发现问题. 放心了. 现在可以正式升级了.

第一步: 备份服务器的所有文件 和 数据库.

按照官方的说明把文件都拷贝上去: http://www.discuz.net/thread-3265731-1-1.html

因为我是用root身份登录到vps上去的,  所以拷贝上去的文件都是属于root的,  nginx 运行所使用的"www"用户是没有权限访问的. 所以要把权限都改对了,进入网站的根目录:

chown www -R *
chgrp www -R *

 

把网站的文件都改到 用户 "www" 用户的名下.

此时可以开始升级了. 运行: http://xxxxxxxx.com/install/update.php

问题出现了, 刚才预升级的时候, 这里就可以点下一步升级了. 但是此时提示 :

"请先升级 UCenter 到 1.6.0 以上版本。如果使用为Discuz! X自带UCenter,请先下载 UCenter 1.6.0, 在 utilities 目录下找到对应的升级程序,复制或上传到 Discuz! X 的 uc_server 目录下,运行该程序进行升级"

(当时没顾上截图)

什么? ucenter版本不对?  不可能啊, 我已经预升级一次了.  不会啊.   于是把服务器上的文件和数据库都恢复到升级前的状态, 进ucenter看, 发现版本号的确是1.6.  所以没问题.

然后又重复官方的教程.

最后运行: http://xxxxxxxx.com/install/update.php.   还是出现一样的提示.

反复按照官方的教程做了三次, 到这都是这个提示, 我确信我没有哪一步做错了. 这就奇怪了.

于是打开update.php文件, 找到这个提示的位置:

1

是这里在比版本号.

上面的code是我改过的, $oldversion 这个变量是我加的, 就是想把版本号显示出来, 看看到底是多少.

重新运行:  http://xxxxxxxx.com/install/update.php.

发现显示出来的版本号是空白. 什么也没有.

继续追踪: "uc_check_version" 函数, 因为版本号是从这的出来的.

搜索到uc_client/client.php

function uc_check_version() {
	$return = uc_api_post('version', 'check', array());
	$data = uc_unserialize($return);
	return is_array($data) ? $data : $return;
}

到了这里还是看不出来.

还是把服务器恢复原样, 和本地比看有什么却别.

恢复服务器文件和数据.

问题出在ucenter, 当然打开后台ucenter看看.

赫然发现: 通信失败

2

 

我很清楚的记得,  原来这里是绿色的通信成功的.

难道是因为和ucenter的通信失败了,  才导致update.php 文件获得ucenter的版本号失败, 所以导致我升级不成功的?

想到这里, 就要跟踪为啥通信会失败了.   (百度搜ucenter 通信失败, 很多人都说是论坛和ucenter之间的设置不一致导致的. 我也反复确认了很多次,设置没有问题.)

我们打开chrome的调试面板, 找到检查通信失败的地址:

点击左侧的 "应用管理", 会发现下面这一条ajax的调用:

3

把这个地址在浏览器中打开:

4

 

发现他果然返回了通信失败的字样.

从上面的url 我们依次找到: uc_server/control/admin/app.php 文件, 并定位到 onping函数:

5

图中可以看到我注掉的调试代码, 都是我自己加的,为了跟踪代码的流程. 我发现流程是 进入了 "else" 块, 然后出来之后 $status就是空白.  下面在判断如果status是1表示成功. 否则就是失败.

我在本地成功的环境下, 重现类似的场景, 发现也是进入了else块, 但是出来的时候 status是1.

那就继续追踪 test_api() 这个函数.

搜索 "test_api", 发现有两处定义, 分别在uc_client\model\misc.php  和 \uc_server\model\app.php.

第一处是空实现, 所以只能看第二处了.

	function test_api($url, $ip = '') {
		echo "in test pi".'<br>';
		$this->base->load('misc');
		if(!$ip) {
			$ip = $_ENV['misc']->get_host_by_url($url);
		}
                echo "line1:".$ip."<br>";
		if($ip < 0) {
			return FALSE;
		}
		echo "line2:".$ip."<br>";
		echo "line3:".$url."<br>";
		$ret = $_ENV['misc']->dfopen($url, 0, '', '', 1, $ip);
		echo "line4 ret value is:".$ret."<br>";
		return $ret;
	}

 

上面, 我加了一些调试代码.

发现 $ret是空白.

那就是dfopen的问题了.

搜索dfopen. 他有多处实现, 但是有两处比较可疑:

\uc_client\model\misc.php 和 \uc_server\model\misc.php

我现在两个实现的入口处都设置echo语句. 发现时走的第二处.

于是进一步跟踪第二处实现:

	function dfopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE	, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE') {
		echo "server model misc dfopen:"."<br>";
		//error_log("[uc_server]\r\nurl: $url\r\npost: $post\r\n\r\n", 3, 'c:/log/php_fopen.txt');
		$return = '';
		$matches = parse_url($url);
		$host = $matches['host'];

............

		if(function_exists('fsockopen')) {
			echo "server model misc dfopen:fsockopen"."<br>";
			$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
		} elseif (function_exists('pfsockopen')) {
			echo "server model misc dfopen:pfsockopen"."<br>";
			$fp = @pfsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
		} else {
			echo "server model misc dfopen:false"."<br>";
			$fp = false;
		}

................

 

我加了一些调试语句在里面.

当加到这里的时候,  想到,是不是 服务器的fsockopen函数被禁用了呢. 于是就没再继续加了. 赶快试. 上传文件, 刷新url.

果然输出了 "server model misc dfopen:false"

 

我擦, 原来是 fsockopen函数被禁用了啊.  赶快上传php的探针,  发现fsockopen果然被禁用了.

6

我这是才想起来,  前几天更换vps的时候, 没注意, 可能忘了打开fsockopen 函数了.

赶快去服务器:/usr/local/php/etc 中 打开php.ini  找到disable_functions这一行. 从中把fsockopen和pfsockopen都删掉.

然后重启php:  service php-fpm restart

然后刷新上面的url, 返回通信成功了.

好了,现在再回到开头.

把文件还原成升级前的样子, 再按照官方说明, 升级文件.

运行: http://xxxxxxxx.com/install/update.php

这次终于正常了, 显示准备完成,可以升级.

后面就比较顺利了. 自动升级数据库, 然后手动去吧缓存更新一下. 就好了.

就到这.

其中还省略了无数的弯路啊.

再次证明一个真理,  看似复杂的问题, 一定是由一个比较愚蠢的原因造成的.

 
byNeil
byNeil.com

原文来自 Blog by Neil, post 记一次艰苦卓绝的Discuz x3 论坛升级过程 转载请注明出处。本站保留一切权力

导入用户信息到discuz ucenter.

上一篇帖子: 直接导入帖子到Discuz 论坛数据库. 结束时说要写一篇导入用户的帖子, 一直没时间, 但是咱不能做太监,不是? 所以今天赶快补上. 在做discuz整合或者迁移是, 很多人可能遇到相同的问题, 就是用户数据怎么导入到discuz中.

discuz 的用户数据其实是存在 ucenter中的. ucenter是什么? 自己百度去. 简单的说, ucenter 就是discuz各个产品之间共享数据的媒介. 所以我们只需要导入到ucenter的表中就可以了.

同样通过上一篇文章中提到的比较方法,  我们发现用户数据时存在 pre_ucenter_members 这一张表中的.  欢迎大家交流心得, 访问我的独立博客 http://byNeil.com  .下面解释一下这个表的列的含义:

1. username:  用户名, 就是用户登录输的用户名.

2. password: 密码, 这个当然不是明文的密码, 至于怎么生成的, 后面再说. password hash = Md5(Md5(password) + salt);

3. email: 就是用户的email, 明文

4. regdate: 是一个int值, linux的时间戳,表示用户的注册时间.

5. salt: 盐.  这个比较有意思, 是为了增加用户密码的安全性的.  这个salt是一个 6位长的字符串, 它本身是注册时随机产生的.  它的作用就是用来混在密码一起产生密码的hash值的.  password hash = Md5(Md5(password) + salt);

 

有了这几列的意思, 导入就简单多了.  如果你知道原来用户的密码(不太可能, 除非是国内某著名网站明文存密码),  或者知道用户密码的 MD5值,  就可以用自己生成的salt来 为用户导入密码了.  这样用户就能用原来的密码登陆新网站了.   如果不知道, 那只有重置所有用户的密码.

具体code就不写了, 各个语言不一样, 自己琢磨.

 

 

 

 
byNeil
byNeil.com

原文来自 Blog by Neil, post 导入用户信息到discuz ucenter. 转载请注明出处。本站保留一切权力

通过.htaccess 的rewriterule 新旧网站的无缝转换,不丢权重

举个例子,  本来有个 A.com 的网站,  做了一定的人气, 有了权重.  因为人流量上升, 这个时候想更换网站程序, 比如做成一个论坛社区.

很简单想到的就是把 A.com 直接指向新的网站就行了.  但是这样, 以前的A.com 的所有的外链都失效了. 对权重非常不利.

主要目标有两个, 第一不丢失以前的外链.  第二让A.com的权重完全转到新的论坛.

我们可以这样实现.  1. 保留原网站, 这是为了确保, 外链都有效.  2, 把 A.com  重定向到  bbs.A.com

这里有一个问题,就是如果把A.com 重定向到了bbs.A.com了, 外链怎么保持呢. 原来的外链都是 http://a.com/abc/def.php 这种形式的.

这个时候想到的就是有条件的重定向,  当用户直接访问A.com的时候, 重定向到bbs.A.con.  如果用户是通过这种形式 http://a.com/abc/def.php 访问的网站,  则不重定向, 让它依然有效.

思路就是检测请求的uri, 如果没有uri 就直接重定向. 如果有uri 则不重定向.

这在php中很容易实现. 但是为了执行效率, 我决定改写.htaccess文件来实现.

在.htaccess 文件的最开始, 插入一下代码


RewriteCond %{REQUEST_URI} =/     #直接输入a.com访问的话,uri不是空,而是斜线:'/'
RewriteCond %{QUERY_STRING} ^$    #正则表达式 ^和$ 放在一起,表示空,之所以加上Querystring,是防止用户这样访问: a.com/?id=124
RewriteRule .* http://bbs.a.com [R=301,L] #重定向到新网址


搞定.

希望大家多多交流.

 
byNeil
byNeil.com

原文来自 Blog by Neil, post 通过.htaccess 的rewriterule 新旧网站的无缝转换,不丢权重 转载请注明出处。本站保留一切权力

直接导入帖子到Discuz 论坛数据库.

因为我的一个网站需要升级成 discuz系统. 所以需要把以前的帖子都导入到discuz中,  当然也包括以前的注册用户也需要导入到discuz中.  导入用户的事情, 待会写另一篇帖子说.  先说导入帖子的事.

以前完全不了解discuz 的数据库结构.  帖子到底怎么存的,完全不知道.  从哪下手呢?

先准备环境.

1. 当让先本地安装php环境, 以便调试. 推荐 WampServer Version . 自己上网搜一下就知道了, 傻瓜操作,一路next安装.

2. 安装discuz 到本地. 过程略.

重点来了,  从哪下手?  (当然可以去找discuz的文档, 但是我没有找到.)

当然是从数据库本身下手最直接.   想法非常简单.   就是手动发一个帖子,  然后对比发帖前后数据库的差异, 就知道要发一个帖子,需要修改哪些数据了.

但是怎么才能知道数据库前后的差异呢.  简单, 发帖前把数据库备份下来, 发完贴再备份一次, 比较这两次的差异.

备份数据库的方法很多, 但是那种方式最简单直接, 最能让人发现其中的差异呢?

我们知道phpmyadmin 这个神器,有一个功能就是导出数据库(或者导出其中的某些表).  而且导出的是 sql文件, 所有的内容都是文本的明文. 这样我们只需要一个文本比较工具,就能对比差异了.

为了完整起见, 其实我也不知道要导出哪些表, 所以就选择导出整个数据库.  先导出一份, origional.sql,   手动去发个帖子, 再导出一份, post.sql, 注意都是导出整个数据库.  还要注意的就是导出的时候, 不能用快速导出, 要点开自定义选项, 找到最下面的 "转储数据时所使用的函数", 改成 replace,  默认是insert.  至于为什么, 等会你就懂了.

 

 

然后请出文本比较神器, beyond Compare.

其中差异不多, 出了一些更新用户积分之类的操作之外,  很快就定位到这两个表:

pre_forum_post 和 pre_forum_thread

细看这两个表的字段不难发现.
post表应该指的是帖子, 其中包含了帖子所有字段,包括标题,内容,时间,作者等等.   thread表表示的是所有主题帖子,  但是thread表并不包含帖子的内容等详细信息, 值包含一个pid. 这个pid就是post表的id.

所以, 所有的帖子, 包括主题帖子以及主题帖子下面的回复应该都是作为一个post放在pre_forum_post表中的.  而 pre_forum_thread 只记录主题帖子的信息, 以及主题帖子对应的post的id.

到这里, 我们就知道了.  我只需要导入帖子到 post表中, 并且, 更新 thread表. 因为我每个帖子都是作为一个主题帖子导入的, 不需要考虑 回复的问题.

其中的pid 和tid 都是一一对应的.   所以更新着两个表就行了.  细节就不说了.

直接导入.

导入很顺利, 但是 导入之后论坛打开,首页, 发现一个帖子也没有. 但是各个板块点开里面有帖子  呃,  说明我们还有数据没有更新对.  怎么办, 再次仔细比较差异.

发现这样一个差异, 在pre_forum_forum表中:

这个表貌似是包含了, 每个版块的概要信息, 就是论坛首页要显示的信息.

比如每个版块的名字, 每个版块总的发帖数, 版块的设置.  以及这个版块最后一个帖子的详细信息. 包括帖子标题, 发帖时间等等.

就是这里用到的信息:

 

知道了这个,就好办了. 我们把帖子导入到post和thread表之后, 在来这里更新 版块的信息就好了.

这里要更新几个具体的字段,

threads: 版块内的主题数.

posts: 版块内的帖子数.

todayposts: 版块内, 今日发帖的个数. 这个是post的个数, 不是thread的个数.

lastpost: 这个字段比较奇葩,  看名字它是表示本版块最新一个帖子.   但它的值比较有意思, 这是一个字符串,  由四部分组成, 每部分之间用 \t 制表符分割.  第一部分是这个帖子的pid,  第二部分是帖子的标题, 第三部分是帖子的发帖时间, 第四部分是帖子的作者名.   这个字段可能是为了提高论坛首页的性能, 有了他之后,首页就负担轻了很多.

其他的字段就不说了.

按这个再来一次.   首先需要把数据库还原到最开始没有导过的样子,  怎么做?   记得刚开始备份的 origional.sql 文件吗? 把他导入到数据库中就好了啊.  刚才让选replase 还记得吗, 如果没有选replace的话, 你现在导入时会失败的,不信你试试.

言归正传.  还原数据库-> 成功.  再次导入帖子(需要更新 pre_forum_post , pre_forum_thread 以及 pre_forum_forum 这三个表.), 一路调试过程自不必说.  如果其中有失败了, 请重新还原数据库, 再视. 经过数次调试之后. 终于成功了.

这个时候打开论坛首页,  每个版块都能正确显示最后发帖信息, 点开每个版块里面的帖子也都正常.  都点几次也都没有问题.   大功告成.....

好了,上线. 等等, 我手一抖, 咱发个帖子玩玩吧. 点发帖.  opps.......

失败啦.....................  肿么办.  难道是我们把数据库改坏了?  ..........不会吧........................

不要慌张, 看看它说什么先.

它在向post表中插入新帖子的时候出错了. 说主键重复.  它插入的时候用的pid主键是1,  但是我刚才已经导入了很多帖子了. 1这个值在post表中早就被占了啊. 当然会出错了.    但是奇怪的是, pid本来就是自增的, 为什么它在插入新帖的时候还要强行指定一个pid呢?   那这个强行指定的pid又是从哪来的呢.  如果能知道从哪来的, 我就能把它改对了.

它有堆栈信息,  程序员的最爱. 一路打开相应的文件. 一探究竟.

在堆栈的第四层, 就是 function_form.php 的941行找到了如下代码:

看样子, 它就是在这指定pid的.

这里应该是在做分表, 我们知道discuz有分表功能, 就是帖子可以分表存放,  因为帖子太多的话, 一个表就会降低性能.

其实了解这个分表不重要.  重要的是看 pid从哪取的.

这里有个表 forum_post_tableid.  这个表比较有意思.  它只有一列pid, 而且还是自增的.   上面的逻辑显示, 当用户添加新帖子时, 会先从这个表中自增一个pid作为帖子的id,  然后再把帖子连带这个pid一起插入到post表中.  了解了这个, 就明白了.  我们刚才导入帖子的时候, pid用的是自增的值.  这是不对的,  应该先从forum_post_tableid表中自增一个pid,  然后连同这个pid和帖子的内容一起插入到post表中, 而不应该直接用post表的自增值.

知道了这个,  改程序,再来.

先还原数据库, 不用说了吧. 然后导入,  经过数次调试之后. 终于通过了. 导入完成.

哈哈, 等等, 我发个帖子先.

 

等等, 我再发一个试试. .............................

发帖成功.

到此, 导入帖子的问题就解决了.

打完收工.

稍后, 再分享一篇,  如何把已经注册的用户 也导入到discuz中.

欢迎大家多多交流.
byNeil
byNeil.com

原文来自 Blog by Neil, post 直接导入帖子到Discuz 论坛数据库. 转载请注明出处。本站保留一切权力

C# mysql 链接 遇到 异常 Authentication with old password no longer supported, use 4.1 style passwords.

用最新版的 mysql connector 去链接 远程的mysql服务器.

遇到 异常 Authentication with old password no longer supported, use 4.1 style passwords.

上网搜, 官方说是服务器的密码版本新,  客户端的版本太低, 连不上. 要更新我的客户端.   但是我的connector 是刚从官方下载的最新的啊. 这不科学啊.

还有人说是去服务器上服务器上的密码存储方式 改成旧版本,这样就可以了.  但是服务器不是我的,  我没有权限去改服务器的配置.

 

最后发现 一个帖子http://stackoverflow.com/questions/13706463/authentication-method-mysql-old-password-not-supported

里面说 MysqL Connector/NET 6.6.x (as of 6.6.2) dropped support for old password style authentication (it was deprecated due to being insecure and there were documented ways to attack it).

其实就是说 .net的connector 已经抛弃了旧的密码方式, 只支持新的密码方式.   突然明白了.   应该是客户端的密码认证方式太新, 而服务器的密码是旧的方式存储的.

所以就要去把服务器的密码存储方式改成新的.  怎么改呢. 找到这个地址  http://writecodepeople.blogspot.com/2013/03/mysql-41-style-password.html

在服务器端只提供了phpmyadmin, 没有console啊.   我记得有个地方可以执行sql语句

于是去服务器上打开phpmyadmin.  打开数据库.  打开Sql tab, 这里可以执行 sql语句.哈哈

执行这两句:

SET old_passwords=FALSE;

SET PASSWORD = PASSWORD('重设密码');

之后, 在用c# connector 去连.  成功.

reffer: http://byNeil.com
byNeil
byNeil.com