分类 编程 下的文章

一种以ID特征为依据的数据分片(Sharding)策略

<p>假如您有一个应用程序,随着业务越来越有起色,系统所牵涉到的数据量也就越来越大,此时您要涉及到对系统进行伸缩(Scale)的 问题了。一种典型的扩展方法叫做“向上伸缩(Scale Up)”,它的意思是通过使用更好的硬件来提高系统的性能参数。而另一种方法则叫做“向外伸缩(Scale Out)”,它是指通过增加额外的硬件(如服务器)来达到相同的效果。从“硬件成本”还是“系统极限”的角度来说,“向外伸缩”一般都会优于“向上伸 缩”,因此大部分上规模的系统都会在一定程度上考虑“向外”的方式。由于许多系统的瓶颈都处在数据存储上,因此一种叫做“数据分片(Database Sharding)”的数据架构方式应运而生,本文便会讨论这种数据架构方式的一种比较典型的实现方式。</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><h1>简介</h1><p>数据分片,自然便是将整体数据分摊在多个存储设备(下文统称为“数据分区”或“分区”)上,这样每个存储设备的数据量相对就会小很多,以此满足系统的性能需求。值得注意的是,系统分片的策略有很多,例如常见的有以下几种:</p><ul> <li>根据ID特征:例如对记录的ID取模,得到的结果是几,那么这条记录就放在编号为几的数据分区上。</li> <li>根据时间范围:例如前100万个用户数据在第1个分区中,第二个100万用户数据放在第2个分区中。</li> <li>基于检索表:根据ID先去一个表内找到它所在的分区,然后再去目标分区进行查找。</li> <li>……</li></ul><p>在这些数据分片策略之中没有哪个有绝对的优势,选择哪种策略完全是根据系统的业务或是数据特征来确定的。值得强调的是:数据分片不是银弹,它对系统的性能和伸缩性(Scalability)带 来一定好处的同时,也会对系统开发带来许多复杂度。例如,有两条记录分别处在不同的服务器上,那么如果有一个业务是为它们建立一个“关联”,那么很可能表 示“关联”的记录就必须在两个分区内各放一条。另外,如果您重视数据的完整性,那么跨数据分区的事务又立即变成了性能杀手。最后,如果有一些需要进行全局 查找的业务,光有数据分片策略也很难对系统性能带来什么优势。</p><p>数据分片虽然重要,但在使用之前一定要三思而后行。一旦踏上这艘贼船,往往不成功便成仁,很难回头。在我的经验里,一个滥用数据分片策略而事倍功半的项目给我留下了非常深刻的印象(当然也有成功的啦),因此目前我对待数据分片策略变得愈发谨慎。</p><p>那么现在,我们便来讨论一种比较常见的数据分片策略。</p><h1>策略描述</h1><p>这里我先描述一个极其简单的业务:</p><ol> <li>系统中有用户,用户可以发表文章,文章会有评论</li> <li>可以根据用户查找文章</li> <li>可以根据文章查找评论</li></ol><p>那么,如果我要对这样一个系统进行数据分片又该怎么做呢?这里我们可以使用上面提到的第一种方式,即对记录的ID取模,并根据结果选择数据所在的分区。根据后两条业务中描述的查询要求,我们会为分区策略补充这样的规则:</p><ul> <li>某个用户的所有文章,与这个用户处在同一数据分区内。</li> <li>某篇文章的所有评论,与这篇文章处在用一数据分区内。</li></ul><p>您可能会说,似乎只要保证“相同用户文章在同一个数据分区内”就行了,不是吗?没错,不过我这里让文章和用户在同一个分区内,也是为了方便许多额外的操作(例如在关系数据库中进行连接)。那么假设我们有4个数据分区,那么它们内部的条目可能便是:</p><table border="1" cellpadding="5" cellspacing="0"> <tbody> <tr> <td>分区0</td> <td>分区1</td> </tr> <tr> <td> <ul> <li>User 4 <ul> <li>Article 8</li> <li>Article 12 <ul> <li>Comment 4</li> <li>Comment 16</li> </ul> </li> </ul> </li> <li>User 12</li> <li>Article 4</li> </ul> </td> <td> <ul> <li>User 1 <ul> <li>Article 5</li> <li>Article 9 <ul> <li>Comment 13</li> <li>Comment 17</li> </ul> </li> </ul> </li> <li>User 5</li> <li>Article 13</li> </ul> </td> </tr> <tr> <td>分区2</td> <td>分区3</td> </tr> <tr> <td> <ul> <li>User 2 <ul> <li>Article 10</li> <li>Article 14 <ul> <li>Comment 6</li> <li>Comment 10</li> </ul> </li> </ul> </li> <li>User 10</li> <li>Article 4</li> </ul> </td> <td> <ul> <li>User 7 <ul> <li>Article 7</li> <li>Article 11 <ul> <li>Comment 3</li> <li>Comment 15</li> </ul> </li> </ul> </li> <li>User 11</li> <li>Article 4</li> </ul> </td> </tr> </tbody></table><p>在 ID为0的分区中,所有对象的ID模4均为0,其他分区里的对象也有这样的规律。那么好,在实际应用中,如果我们需要查找“ID为2的用户”,便去第2分 区搜索便是;如果要查找“ID为8的文章的所有评论”那么也只要去第0分区进行一次查询即可。既然查询不成问题,那么我们该如何添加新记录呢?其实这也不 难,只要:</p><ul> <li>添加新用户时,随机选择一个数据分区</li> <li>添加新文章时,选择文章作者所在分区(可根据Article的UserID求模得到)</li> <li>添加新评论时,选择文章所在分区(可根据Comment的ArticleID求模得到)</li></ul><p>但 是,我们又如何保证新纪录的ID正好满足我们的分区规律?例如我们向第3分区添加的新数据,则它的ID必须是3、7、11等等。以前,我们可能会使用数据 库的自增列作为ID的值,但这似乎不能满足我们“取模”的要求。以前我们可能还会使用GUID,但是我们如何生成一个“被4模于3”的GUID呢?其实我 们还是可以使用自增ID来解决这个问题,只不过需要进行一些简单的设置。例如在SQL Server中,默认的自增ID属性为IDENTITY(1, 1),表示ID从1开始,以1为间距自动增长。于是我们在创建数据分区的时候,每个自增列的属性则可以设置为:</p><ul> <li>分区0:IDENTITY(4, 4)</li> <li>分区1:IDENTITY(1, 4)</li> <li>分区2:IDENTITY(2, 4)</li> <li>分区3:IDENTITY(3, 4)</li></ul><p>这样,ID方面的问题便交由数据库来关心吧,我们的使用方式和以前并没有什么区别。</p><h1>缺陷</h1><p>那么这个数据分片策略有什么缺陷呢?当然缺陷还是有很多啦,只是大多数问题可能还是要和业务放在一起考虑时才会凸显出来。不过有一个问题倒和业务关系不大:如果数据继续增长,单个数据分区的数据量也超标了,怎么办?</p><p>自 然,继续拆分咯。那么我们使用什么分区规则呢?和原先一致吗?我们举个例子便知。假设我们原有4个分区,有一个ID为1的用户落在第1分区里,他的文章也 都在这个分区里,ID分别是1、5、9、13、17等等。于是在某一天,我们需要将分区数量提高到5个(财力有限,一台一台来吧),在重新计算每篇文章所 在的分区之后,我们忽然发现:</p><ul> <li>ID为1的文章,模5余1,处在分区1。</li> <li>ID为5的文章,模5余0,处在分区0。</li> <li>ID为9的文章,模5余4,处在分区4。</li> <li>ID为13的文章,模5余3,处在分区3。</li> <li>ID为17的文章,模5余2,处在分区2。</li></ul><p>呼,5 个分区都齐了!这说明,如果我们保持记录原来的ID不变,是没有办法直接使用之前的分区规则——无论您扩展成几个分区,(即便是从4个到8个)也只能“缓 解”也不能“解决”这个情况。那么这时候该如何是好呢?例如,我们可以重新分配记录,改变原有ID,只是这么做会产生一个问题,便是外部URL可能也会随 着ID一起改变,这样对SEO的折损很大。为此,我们可以制作一个查询表:例如在查询小于1234567的ID时(这是“老系统”的最大ID),假设是 100,则根据查询表得知这条记录的新ID为7654321,再以此去数据源进行查找。解决这类问题的方法还有几种,但无论怎么做都会对新系统带来额外的 复杂度。而且,一次扩展也罢,如果以后还要有所扩展呢?</p><p>consistent-hahsing</p><p>有朋友可能会说,取模自然会带来这样的问题,那么为什么不用一致性哈希(Consistent Hash)呢? 现在一致性哈希是个很流行的东西,和Memcached一样,如果不用上就会被一些高级架构师所鄙视。不过在这里一致性哈希也不能解决问题。一致性哈希的 目的,是希望“在增加服务器的时候降低数据移动规模,让尽可能多的数据保留在原有的服务器”上。而我们现在的问题却是“在增加服务器的时候,让特征相同的 数据同样放在一起”。两个目标不同,这并不是一致性哈希的应用场景。</p><p>我在以前的一个项目中曾经用过这样的方法:根据对访问量与数据量的 预估,我们认为使用最多24个分区便一定可以满足性能要求(为什么是24个?因为它能被许多数字整除)。于是,从项目第一次在生产环境中部署时便创建了 24个数据分区,只不过一开始只用了2台服务器,每台服务器放置12个数据分区。待以后需要扩展时,则将数据分区均匀地迁移到新的服务器上即可。我们团队 当时便是用这种方法避免尴尬的数据分配问题。</p><p>没错,数据分区的数目是个限制,但您真认为,24个数据分区还是无法满足您的项目需求吗? 要知道,需要用上24个数据分区的项目,一般来说本身已经有充分的时间和经济实力进行架构上的重大调整(也该调整了,几乎没有什么架构可以满足各种数据规 模的需求)。此外,无论是系统优化还是数据分片都可以同时运用其他手段。</p><p>不过,我们目前还是想办法解决这个问题吧。</p><h1>策略改进</h1><p>我们之所以会遇到上面这个问题,在于我们没有选择好合适的策略,这个策略把一些重要的“要求”给“具体化”了,导致“具体化”后的结果在外部条件改变的时候,却无法重新满足原有的“要求”。还是以前面的案例来说明问题,其实我们“要求”其实是:</p><ul> <li>某个用户的所有文章,与这个用户处在同一数据分区内。</li> <li>某篇文章的所有评论,与这篇文章处在用一数据分区内。</li></ul><p>而我们“具体化”以后的结果却是:</p><ul> <li>某个用户的所有文章ID,与这个用户的ID模4后的余数相同。</li> <li>某篇文章的所有评论ID,与这篇文章的ID模4后的余数相同。</li></ul><p>之 所以能如此“具体化”,这是因为有“4个分区”这样的前提条件在,一旦这个前提条件发生了改变,则杯具无法避免。因此,我们在制定规则的时候,其实不应该 把前提条件给过分的“具体化”——具体化可以,但不能过度,得留有一定空间(这个稍后再谈)。打个比方,还是前面的条件(XX和XX处在同一数据分区 内),但我们换一种具体化的方式:</p><ul> <li>某个用户的所有文章ID的前缀,便是这个用户的ID。例如,ID为1的用户的所有文章,其ID便可能是1-A1、1-A2、1-A3……</li> <li>某篇文章的所有评论ID,与这个文章的ID使用相同前缀。例如,ID为3-A1的文章的所有评论,其ID便可能是3-C1、3-C2、3-C3……</li></ul><p>使 用这个策略,我们便可以保证与某个用户相关的“所有数据”都共享相同的“特征”(ID的前缀都相同),然后我们便可以根据这个特征来选择分区——例如,还 是以“取模”的方式。此时,我们已经确保了“相同分区内的所有数据都具备相同的特征”,即便分区数量有所调整,我们也只需要根据特征重新计算分区即可,影 响不大。而以前为什么不行?因为“模4的余数”只是“结果”而不是“特征”,这里的“特征”应该是“追本溯源后的用户ID相同”,而这一点已经体现在新的 策略中了。</p><p>还是通过图示来说明问题吧。假设原有4个分区,使用“取模”的策略:</p><table border="1" cellpadding="5" cellspacing="0"> <tbody> <tr> <td>分区0</td> <td>分区1</td> </tr> <tr> <td> <ul> <li>User 4 <ul> <li>Article 4-A1</li> <li>Article 4-A2 <ul> <li>Comment 4-C1</li> <li>Comment 4-C2</li> </ul> </li> </ul> </li> <li>User 12</li> <li>Article 12-A3</li> </ul> </td> <td> <ul> <li>User 1 <ul> <li>Article 1-A4</li> <li>Article 1-A5 <ul> <li>Comment 1-C3</li> <li>Comment 1-C4</li> </ul> </li> </ul> </li> <li>User 5</li> <li>Article 5-A6</li> </ul> </td> </tr> <tr> <td>分区2</td> <td>分区3</td> </tr> <tr> <td> <ul> <li>User 2 <ul> <li>Article 2-A7</li> <li>Article 2-A8 <ul> <li>Comment 2-C5</li> <li>Comment 2-C6</li> </ul> </li> </ul> </li> <li>User 10</li> <li>Article 10-A9</li> </ul> </td> <td> <ul> <li>User 7 <ul> <li>Article 7-A10</li> <li>Article 7-A11 <ul> <li>Comment 7-C7</li> <li>Comment 7-C8</li> </ul> </li> </ul> </li> <li>User 11</li> <li>Article 11-A12</li> </ul> </td> </tr> </tbody></table><p>当分区数量调整为5个之后(为了避免分区3空缺,我又补充了一些对象):</p><table border="1" cellpadding="5" cellspacing="0"> <tbody> <tr> <td>分区0</td> <td>分区1</td> </tr> <tr> <td> <ul> <li>User 10 <ul> <li>Article 10-A9</li> </ul> </li> <li>User 5</li> <li>Article 5-A6</li> </ul> </td> <td> <ul> <li>User 1 <ul> <li>Article 1-A4</li> <li>Article 1-A5 <ul> <li>Comment 1-C3</li> <li>Comment 1-C4</li> </ul> </li> </ul> </li> <li>User 11</li> <li>Article 11-A12</li> </ul> </td> </tr> <tr> <td>分区2</td> <td>分区3</td> </tr> <tr> <td> <ul> <li>User 2 <ul> <li>Article 2-A7</li> <li>Article 2-A8 <ul> <li>Comment 2-C5</li> <li>Comment 2-C6</li> </ul> </li> </ul> </li> <li>User 12</li> <li>Article 12-A3</li> <li>Article 7-A10</li> <li>Article 7-A11 <ul> <li>Comment 7-C7</li> <li>Comment 7-C8</li> </ul> </li> <li>User 7</li> </ul> </td> <td> <ul> <li>User 8 <ul> <li>Article 8-A12</li> <li>Article 8-A13 <ul> <li>Comment 8-C9</li> <li>Comment 7-C10</li> </ul> </li> </ul> </li> </ul> </td> </tr> <tr> <td>分区4</td> <td> </td> </tr> <tr> <td> <ul> <li>User 4 <ul> <li>Article 4-A1</li> <li>Article 4-A2 <ul> <li>Comment 4-C1</li> <li>Comment 4-C2</li> </ul> </li> </ul> </li> </ul> </td> <td> </td> </tr> </tbody></table><p>是不是很合理?</p><p>值 得一提的是,只要满足了“特征”这个要求,其实选择分区的方式并没有什么限制。例如,我们可以不用“取模”的方式,而是使用“一致性哈希”——没错,这里 就是一致性哈希的使用场景了。在利用“一致性哈希”来选择分区之后,在添加服务器的情况下便可以相对减少数据的迁移数量了。</p><p>当然,在实 现时还可以运用一些技巧。例如,我们的特征并非一定要“把用户ID作为前缀”——毕竟用户ID可能比较长,作为ID前缀还真有些难看(请想象把GUID作 为ID前缀,再加上另一个GUID作为ID主体的情景)。此时,我们可以把前提条件先进行一定程度的“具体化”(但就像之前提到的,不能过度),例如我们 可以把用户ID先进行取模,可能是1000万,便可以得到一个落在较大区间范围内的数字。然后,再把这个数字作BASE64编码,一下子前缀就缩小为4个 字符以内了。而且,1000万这个区间范围,无论是使用取模还是一致性哈希的方式来选择分区都非常可行,一般不会造成什么问题。</p><h1>总结</h1><p>数 据分片是系统优化的常用设计方式之一。正如前文所说的那样,数据分片的做法很多,本文提到的方式只是其中一种方式。这种根据ID特征的分片方式比较容易遇 到的问题之一,便是在数据分区数量改变时造成的规则冲突,这也正是我这篇文章所讨论的主要内容。从这个角度看来,其他一些分片方式,如创建时间也好,查找 表也罢,这样的问题反而不太常见。如果您有这方面的经验或是疑惑,也欢迎与我进行交流。</p><p>现在Web 2.0网站越来越热门了,此类项目的数据量也越来越大,从近几年的讨论形式可以看出,越来越多的人在强调什么大规模、高性能、或是海量数据。然后,似乎每 个人都会横向切分、纵向切分、缓存、分离。我猜,再接下来,估计又会有许多人以用关系型数据库为耻了吧?但是,想想这样的问题:博客园和JavaEye都 是国内技术社区的翘楚,它们都只用了1台数据库服务器。StackOverflow世界上最大的编程网站(它是使用ASP.NET MVC写的,兄弟们记住这个经典案例吧),似乎也只用了1台还是2台数据库服务器(可能配置比较高)及SQL Server。因此,即便是单台服务器,即便是使用关系型数据库,它在性能方面的潜力也是非常之高的。</p><p>因 此,数据分片应该只在需要的时候才做,因为它带来的复杂度会比中心存储的方式高出很多。这带来的结果是,可能您的应用程序还没有用足架构的能力就已经失败 了,这样各种投资也已经浪费了。假如您一开始用最简单的方式去做,可能很快会带来成长所需要空间及资源,此时再做更多投资进行架构优化也不迟——架构不是一蹴而就,而是演变得来的。当然,第一次投入多少复杂度是个需要权衡的东西,这也是考验架构师能力的地方。架构不是空中楼阁,而是各种真实资源调配的结果。</p>

- 阅读剩余部分 -

支付宝,网银在线,快钱 3大支付接口的集成与对比,统合实现

<p>[支付宝参数设置案例]
t1 = "https://www.alipay.com/cooperate/gateway.do?";
t4 = "images/alipay_bwrx.gif"
t5 = "推荐使用支付宝付款"
service = "trade_create_by_buyer"
agent = "商户号"
partner = "商户号"
sign_type = "MD5"
subject = "订单号:"&dingdan 
body = "seadori商城"</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><p>
out_trade_no = 变量 '客户网站订单号,(现取系统时间,可改成网站自己的变量)
price = 变量 'price商品单价 0.01~50000.00
discount = "0" '商品折扣
show_url = "www.domain.com" '商品展示地址(可以直接写网站首页网址)
quantity = "1" '商品数量
payment_type = "1" '支付类型,(1代表商品购买)
logistics_type = "POST" '物流种类(快递)
logistics_fee = "0.00" '物流费用
logistics_payment = "BUYER_PAY" '物流费用承担(买家付)
logistics_type_1 = "EMS"
logistics_fee_1 = "0.00"
logistics_payment_1 = "BUYER_PAY" '物流费用承担(买家付)
seller_email = "xxx@xxxl.net" '(必须填)
key = "xxxxxx" '(必须填)
notify_url= "http://domain/alipay/Alipay_Notify.asp";</p><p>[网银在线参数设置案例]
key = "XXXX"
v_mid = "商户号"
v_amount="金额变量"
v_moneytype = "CNY" 选择人民币
style="0"
v_url="http://www.damain.com/Receive.asp";
remark1=""
remark2=""
下面参数直接调用上面的定义, 不用修改。
<input type="hidden" name="v_md5info" size="100" value="<%=v_md5info%>">
<input type="hidden" name="v_mid" value="<%=v_mid%>">
<input type="hidden" name="v_oid" value="<%=v_oid%>">
<input type="hidden" name="v_amount" value="<%=v_amount%>">
<input type="hidden" name="v_moneytype" value="<%=v_moneytype%>">
<input type="hidden" name="v_url" value="<%=v_url%>">
<input type="hidden" name="style" value="<%=style%>">
<input type="hidden" name="remark1" value="<%=remark1%>">
<input type="hidden" name="remark2" value="<%=remark2%>"></p><p>[快钱参数设置案例]
merchant_id = "XXXXX" '''商户编号
merchant_key = "XXXXX" '''商户密钥
orderid = 变量 '''订单编号
amount = 变量 '''订单金额
curr = "1" '''货币类型,1为人民币
isSupportDES = "2" '''是否安全校验,2为必校验,推荐
merchant_url = "http://www.domaini.com/99bill/receive.asp"; '''支付结果返回地址
pname = request("pname") '''支付人姓名
commodity_info = "xxx商品" '''商品信息
merchant_param = "" '''商户私有参数 (不用填写)</p><p>[比较]
(1)快钱和玩银在线一般只使用3个文件, SEND, RECEIVE, MD5 
SEND 文件发送参数,RECEIVE文件返回参数结果,MD5进行加密验证。 
而支付宝一般有一个INDEX(可以调用到网站的支付页面),INDEX调用网站的变量参数,然后发送到PAYTO文件,INDEX和PAYTO文件组合起来相当于SEND的功能,而其他的都相同。</p><p>(2)支付宝大部分是安全支付平台,顾客收到货后支付宝才会给商户顾客支付的额度,而快钱和网银在线,钱杀直接到商户的帐里面。
3家公司的费率都是1%,而没有初装费或者年费, 不过过不了多久,肯定会有这类收费的。
所有支付系统都是有交易失败的情况的, 支付宝的失败率最少, 然后是网银,然后是快钱。
支付宝对客户来说是最为安全的,因为可以保证不被商家欺骗,但交易过程会慢很多;网银是中国B2C支付系统中最成熟的,很多大公司都用网银,网银对商家来 说是最合适的;快钱和网银基本上一样, 只是快钱对快钱普通用户有费率优惠,快钱使用者以快钱帐户购买商家产品的时候会比网银占一点便宜,而且快钱也可以象网银那样, 不需要快钱帐户直接进行银行支付的。但快钱的系统交易失败率并不低。
想起以前用过的中国移动和中国联通的支付系统,一:手机支付接口开发调试的时候比较麻烦,特别是联通的, 是非常复杂的,有些公司开发手机支付接口花费1~2个月, 移动和联通的技术支持也非常差,很多情况都不会理睬,而最重要的是,他们的费率是20~40%, 这和网银的1%比起来,是晕死人的事情,不过在中国, 手机用户远比网上银行用户多,而中国的移动公司是垄断形的,这也是中国手机花费高的原因,要知道独裁政治和垄断企业是走到一起的。</p><p>[统合]
很多网站一般在支付结果页面只集成一个支付渠道。因为多个支付渠道集成在一个页面的时候会有一些问题出现。
(1)在一个支付页面内集成不同支付渠道的时候:
一般只支持一个接口。多个接口的时候调用的MD5,PAYTO等文件的定义不同,在一个页面头文件里无法引用多个文件。
可以不调用MD5,只调用PAYTO来实现3个支付系统全部运作, 但这个风险是很大的,没有进行MD5的加密,客户支付的钱不能保证到商户的帐户里面。这是有安全隐患的。PAYTO里面引用的MD5和外部SEND引用的 MD5几乎是一样的问津, 但不同支付渠道对MD5引用的路径会不同,肯定是有安全隐患的。
(2)在一个页面放多个按钮, 点击按钮跳转到SEND,INDEX等页面进行支付。
这个方法是最为方便的,但后面打开的SEND和INDEX等页面必须调用前面支付页面里的参数变量。
调用前一页参数的方法我在其他文章里详细说明过,在此不进行说明。</p>

- 阅读剩余部分 -

如何设置IIS播放FLV流媒体

<p>微软的windows2003 server默认并没有开启支持flv文件格式的功能,其实win2003是支持FLV文件的。原因是由于windows server 2003上并没有.FLV的这种mime-type类型,对于这一点Adobe给出了它的解决方案。请按以下步骤操作。</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><p>如下:</p><p>1. 在window2003服务器上,找开IIS管理器。
2. 展开本地服务器名称,右击选择属性,在Internet信息服务标签上,点击最下方的计算机MIME映射下面的编辑按钮。
3. 点击”新类型”按钮,扩展名添上”.FLV”,内容类型(MIME)添上“flv-application/octet-stream”
4. 点击确定
5. 重新启动www服务。</p><p>尽管adobe提供了这种解决方法可以让.FLV工作,但仍会在许多情况下会出现意想不到的结果,仍会有许多.FLV不能正常的工作。下面有一种解决方法:前几步是一样的。</p><p>1. 在2003服务器上,找开IIS管理器。
2. 展开本地服务器名称,右击选择属性,在Internet信息服务标签上点击最下方的计算机MIME映射下面的编辑按钮。
3. 点击”新类型”按钮,扩展名添上”.FLV”,内容类型(MIME)添上"video/x-flv"
4. 点击确定
5. 重新启动www服务。</p><p>
对于FLV类型: 
打开Internet Information Services Manager(IIS),选择“本地计算机”-->用户站点-->打开“属性”-->“HTTP头”-->“MIME类型”- ->“新建”。扩展名=“.flv”MIME类型=“flv-application/octet-stream”,保存退出即可。</p><p>对于RMVB类型: 
打开Internet Information Services Manager(IIS),选择“本地计算机”-->用户站点-->打开“属性”-->“HTTP头”-->“MIME类型”- ->“新建”。扩展名=“.rmvb”MIME类型=“application”,保存退出即可。</p>

- 阅读剩余部分 -

利用新浪微博第三方认证OAuth登录自己的网站

<p>1. 类库下载:</p><p>用于新浪微博开放平台的PHP Lib. 内含能直接使用的DEMO.</p><p>SAE上OAuth版本内置了,不用下载,参考http://blog.sae.sina.com.cn/?p=107*</p><p>Basic认证版本在这里下载 http://code.google.com/p/libweibo/downloads/list</p><p>新浪官方下载页面: http://open.t.sina.com.cn/wiki/index.php/SDK#PHP</p><p>新浪宣布2011.6.1全面停止 Basic Auth的支持,所以要请开发者注意这个问题了</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><p> </p><p>2. 调用新浪微博接口必须是要申请一个应用的,申请应用成功之后会得到一个App key号和App Secret号,我们也需要通过这两个参数来请求授权</p><p>新浪官方地址:http://t.sina.com.cn/11051/3f4cXR5Tej</p><p> </p><p>3. demo使用教程:</p><p>下载,然后解压,修改config.php中的App Key和App Secret</p><p>打开index.php,将13行最后一个url改成你网站对应的callback.php的url</p><p>上传到PHP空间即可</p><p> </p><p>4. 开发完成后,再去新浪微博网站上提交申请即可</p><p> </p><p>5. 我觉得这个第三方登录其实意义也不大,从新浪微博传过来的参数,没几样是我需要的,邮箱不肯给,有用的就给了个用户名的参数,但是用户名有什么用啊,我也不能用这个用户名直接给用户注册一个账号,因为万一有重复的用户名就出错了,所以还是需要用户自行选择是绑定已有的网站账号呢,还是根据这个第三方认证创建一个新账号。这些都做完以后,用户可以根据第三方认证自动登录。用户其实该填的还都得填,没一点方便,这个无非就是几个网站之间表面性的提高点耦合度,提高点点击量,无他。</p><p> </p><p>6.  出现的问题</p><p>我在本机测试的时候,一切ok。传到服务器的时候出错了,点击第三方登录按钮时,打开的页面总是“找不到页面”。后来根据新浪的类库代码一步一步的找下去,发现原因了,他用到了curl模块,我的服务器恰好是不支持这个的。得,重新编译php吧,让他支持curl吧。教程如下</p><p> </p><p> </p><p>7. Linux下为PHP添加CURL扩展库的教程</p><p>本次编译只是单独编译php的扩展库,然后将编译好的php扩展库加到现在运行的php中,不对现在运行的php重新编译,所以对现在运行的php没有任何影响。</p><p>假如原先编译的php目录在/usr/local/php4目录下;apache在/usr/local/apache2目录下;php源代码在/usr/local/src/php-4.4.7目录下。如果实际目录与假定的目录不一致,则在下面的命令中做调整。</p><p>1. 找到当前运行的php版本的源代码目录,如 php-4.4.7。进入curl扩展库目录。
$cd /usr/local/src/php-4.4.7/ext/curl</p><p>2. 调用phpize程序生成编译配置文件。<br />$/usr/local/php4/bin/phpize</p><p>3. 编译扩展库,分别执行下面的configure和make命令。
$./configure -with-php-config=/usr/local/php4/bin/php-config<br />##configure这一步执行通过后,再执行make命令,如果configure执行不通过,则查找错误原因。<br />$make
##make成功执行后,生成的扩展库文件在当前目录的 modules 子目录下,
    如 /usr/local/src/php-4.4.7/ext/curl/modules/curl.so</p><p>4. 配置php.ini文件
##将编译好的扩展库文件复制到apache2 modules目录下。
$cp /usr/local/src/php-4.4.7/ext/curl/modules/curl.so /usr/local/apache2/modules/.
##可以通过查看phpinfo信息来确定php.ini文件位置,然后编辑。
##在php.ini文件中找到设置扩展目录的位置,然后将扩展路径设置到apache2 modules目录下。
   extension_dir = “/usr/local/apache2/modules/”
##在php.ini的添加扩展库位置,设置要添加的扩展库。
   extension=curl.so
##以后如果还要添加别的扩展库的话,则只需先将php扩展库编译好,然后copy到apache2 modules目录下,
##然后再在这个位置,添加一行将编译后的扩展库文件名加上即可。</p><p>5. 重启apache,查看phpinfo信息,即可看到刚才添加进去的curl扩展库。</p>

- 阅读剩余部分 -

MXML 语法

<p>XML 是Adobe Flex™应用中一种用于展示用户界面组件的XML 语言
MXML 基本语法
大多数MXML标签相当于ActionScript 3.0的类或者类属性。Flex解析MXML标签,并将其编译成一个包含对应ActionScript对象的SWF文件。
ActionScript 3.0 使用的语法基于 ECMAScript语言规范草案(第4版)。ActionScript 3.0 包含下列特性:
正式的类定义语法
正式的包结构</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><p>
键入变量、参数和返回值(仅在编译期)
隐含的getter和 setter,使用 get 和 set 关键字
继承
公共和私有成员
静态成员
类型转换符
关于ActionScript 3.0的更多信息,参见 Using ActionScript。
MXML文件命名</p><p>MXML文件名必须遵守下列命名约定:
文件名必须是有效的ActionScript标识符,这意味着必须以字母或下划线(_)开头,其后只能包含字母、数字和下划线。
文件名不能和ActionScript类名、组件id值相同,或者单词是application。不要使用和mx命名空间中MXML标签名相匹配的文件名。
文件名必须以小写字母.mxml作为文件后缀。
表示 ActionScript 类的标签使用</p><p>对应于ActionScript类的MXML标签采用的命名约定和ActionScript类相同。 类名以大写字母开头,大写字母区分类名中的单词。比如,当一个标签对应一个ActionScript类时,它的属性对应于该类的属性和事件。
设置组件属性
MXML中组件属性使用的命名约定和对应的ActionScript属性相同。属性名以小写字母开头,大写字母区分属性名中的单词。
大多数组件属性设置和标签属性一样,形式如下:
<mx:Label width="50" height="25" text="Hello World"/>
所有组件属性可以设置为子标签,形式如下:
<mx:Label>     <mx:width>50</mx:width>     <mx:height>25</mx:height>     <mx:text>Hello World</mx:text> </mx:Label>
当设置属性值为一个复杂的Object时,通常可以使用子标签,因为不能指定一个复杂的Object作为标签属性值。在下面的例子中,使用子标签将ComboBox控件的dataProvider设置为一个ArrayCollection对象:
<mx:ComboBox>     <mx:dataProvider>         <mx:ArrayCollection>             <mx:String>AK</mx:String>             <mx:String>AL</mx:String>             <mx:String>AR</mx:String>         </mx:ArrayCollection>     <mx:dataProvider> </mx:ComboBox>
在前面例子中,使用子标签设置属性的一个限制是子标签命名空间前缀mx:必须匹配组件标签的命名空间前缀。
每一种组件属性均是以下类型之一:
标量属性,比如数字或字符串
标量值数组,比如数字或字符串数组
ActionScript 对象
ActionScript 对象数组
ActionScript 属性
XML 数据
Adobe建议你使用标签属性赋标量值,而使用子标签赋一些复杂的类型,比如ActionScript对象。
设置标量属性</p><p>通常指定标量属性值作为组件标签的属性,如下所示:
<mx:Label width="50" height="25" text="Hello World"/>
使用常量设置属性</p><p>很多组件属性的有效值由静态常量定义,这些静态常量在ActionScript类中定义。MXML中可以使用静态常量设置属性值,也可以使用静态常量值,如下所示:
<!-- 使用静态常量设置属性。 --> <mx:HBox width="200" horizontalScrollPolicy="{ScrollPolicy.OFF}">     ... </mx:HBox>   <!—使用静态常量值设置属性。 --> <mx:HBox width="200" horizontalScrollPolicy="off">     ... </mx:HBox>
HBox容器定义了horizontalScrollPolicy属性,用于定义容器水平滚动条的操作。本例中,你显式设置horizontalScrollPolicy属性,禁用了水平滚动条。
第一个例子中使用ScrollPolicy类定义的静态常量OFF设置horizontalScrollPolicy属性。在MXML中,设置属性值为静态常量时必须使用数据绑定语法。使用静态常量的好处是Flex编译器能识别不正确的属性值,在编译期会报错。
不过,你也设置horizontalScrollPolicy属性值为静态常量的值。静态常量OFF 的值为“off”。当你使用静态常量值设置属性值时,Flex编译器不能确定是否使用了一个不支持的值。如果你设置属性不正确,直到报运行时错误才会知道。
在ActionScript中,应当总是使用静态常量设置属性值,如下所示:
var myHBox:HBox = new HBox(); myHBox.horizontalScrollPolicy=ScrollPolicy.OFF;
设置默认属性</p><p>很多Flex组件定义了一个默认属性。default_property是MXML标签属性,如果你不明确指定该属性,则默认为MXML标签内的内容。比如,考虑以下MXML标签定义:
<mx:SomeTag>     anything here </mx:SomeTag>
如果该标签定义了默认属性default_property,那么前面的标签定义相当于如下代码:
<mx:SomeTag>     <default_property>         anything here     </default_property> </mx:SomeTag>
也相当于以下代码:
<mx:SomeTag default_property="anything here"/>
默认属性为设置单个属性提供了一种简写机制。比如ComboBox,默认属性是dataProvider。因此,下列代码中两个ComboBox的定义是等价的:
<?xml version="1.0"?> <!-- mxmlDefProp.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; >     <!-- 省略默认属性。 -->     <mx:ComboBox>         <mx:ArrayCollection>             <mx:String>AK</mx:String>             <mx:String>AL</mx:String>             <mx:String>AR</mx:String>         </mx:ArrayCollection>     </mx:ComboBox>     <!-- 明确指定默认属性。 -->     <mx:ComboBox>         <mx:dataProvider>             <mx:ArrayCollection>                 <mx:String>AK</mx:String>                 <mx:String>AL</mx:String>                 <mx:String>AR</mx:String>             </mx:ArrayCollection>         </mx:dataProvider>     </mx:ComboBox>    </mx:Application>
不是所有Flex组件都定义有默认属性。要确定每一个组件的默认属性,参见《Adobe Flex Language Reference》。
创建一个自定义组件时也可以定义默认属性。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的“自定义组件的原数据标签”。
使用反斜杠符号的转义字符</p><p>在MXML中设置属性值时,可以以反斜杠字符()作为前缀对保留字进行转义,如下所示:
<?xml version="1.0"?> <!-- mxmlEscapeChar.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"; >     <mx:Label text="{}"/> </mx:Application>
本例中,你想在文本字符串中使用大括号({ })。但是Flex使用大括号表示数据绑定操作。因此,你应在每一个大括号前加反斜杠()使得MXML编译器将它们解释为字面意义。
使用反斜杠字符设置String 属性</p><p>当MXML 中String类型的属性值含反斜杠时,MXML编译器会自动对反斜杠进行转义。因此,总是将“&rdquo;转换成“\”。
这是必须的,因为ActionScript编译器将“\”认为字符“&rdquo;,当初始化属性值时会去掉第一个反斜杠。
注意:不要使用反斜杠()作为应用目录的路径分隔符。应当总是使用正斜杠(/)作为分隔符。
在String值中包含换行符</p><p>对于String类型的属性,有两种方式在String中插入换行符:
在MXML的String值中插入&#13;代码
在ActionScript 用来初始化MXML 属性的String变量中插入“n”
要使用&#13;代码插入换行符,可以在MXML的属性值中包含该代码,如下所示:
<mx:TextArea width="100%" text="Display&#13;Content"/>
要使用ActionScript String变量插入换行符,可以创建一个ActionScript变量,然后使用数据绑定设置MXML中的属性,如下所示:
<mx:Script>     <![CDATA[         [Bindable]         public var myText:String = "Display" + "n" + "Content";     ]]> </mx:Script> <mx:TextArea width="100%" text="{myText}"/>
本例中,TextArea控件的text属性值被设置为包含一个换行符。
注意,本例中在属性定义前有[Bindable]元数据标签。元数据标签指定了myText属性可以作为数据绑定表达式的source。运行时当属性变化时数据绑定会自动将一个对象的source属性值复制给另一个对象的destination属性。
如果你省略了元数据标签,编译器会发出警告,指出该属性不能作为数据绑定的source。更多信息,参见绑定数据。
设置标量值数组</p><p>当一个类以数组作为它的属性值时,可以在MXML中使用子标签表示该属性。下面例子中的组件有一个dataProvider属性,包含数字数组:
<mx:List width="150">     <mx:dataProvider>         <mx:Array>             <mx:Number>94062</mx:Number>             <mx:Number>14850</mx:Number>             <mx:Number>53402</mx:Number>         </mx:Array>     </mx:dataProvider> </mx:List>
数组元素外的<mx:Array>和</mx:Array>标签可选。因此,这个例子代码也可以写成以下所示:
<mx:List width="150">     <mx:dataProvider>         <mx:Number>94062</mx:Number>         <mx:Number>14850</mx:Number>         <mx:Number>53402</mx:Number>     </mx:dataProvider> </mx:List>
本例中,因为dataProvider属性的数据类型定义为数组,因此Flex会自动将三个数字定义转换为一个三元素数组。
组件开发人员可能在定义数组元素数据类型的组件定义内已经指定了一些其他信息。比如,如果开发人员指定dataProvider属性只支持String元素,那么这个例子会报编译错误,因为你指定了数字。《Adobe Flex Language Reference》描述了用来定义数组元素要求数据类型的Array属性。
设置Object 属性</p><p>当组件以对象作为属性值时,可以在MXML中用含标签属性的子标签表示该属性:
<mynamespace:MyComponent>     <mynamespace:nameOfProperty>         <mynamespace:typeOfObject prop1="val1" prop2="val2"/>     </mynamespace:nameOfProperty> </mynamespace:MyComponent>
下面的例子给出了一个定义Address对象的ActionScript类。该对象在下一个示例中作为PurchaseOrder组件的属性。
class Address {     public var name:String;     public var street:String;     public var city:String;     public var state:String;     public var zip:Number; }
以下示例给出了一个ActionScript类,定义了一个含Address类型属性的PurchaseOrder组件:
import example.Address;   class PurchaseOrder {     public var shippingAddress:Address;     public var quantity:Number; ... }
MXML中定义了PurchaseOrder组件,如下所示:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example"> <mynamespace:shippingAddress> <mynamespace:Address name="Fred" street="123 Elm St."/> </mynamespace:shippingAddress> </mynamespace:PurchaseOrder>
如果shippingAddress属性值是Address的子类(比如DomesticAddress),你可以声明该属性值,如下所示:
<mynamespace:PurchaseOrder quantity="3" xmlns:e="example">     <mynamespace:shippingAddress>         <mynamespace:DomesticAddress name="Fred" street="123 Elm St."/>     </mynamespace:shippingAddress> </mynamespace:PurchaseOrder>
如果该属性被显式设置为Object类型,如同下面例子中value属性,可以使用<mx:Object>标签指定一个匿名对象。
class ObjectHolder { public var value:Object }
下面的例子给出了如何指定一个匿名对象作为value属性的值:
<mynamespace:ObjectHolder>     <mynamespace:value>         <mx:Object foo='bar'/>     </mynamespace:value> </mynamespace:ObjectHolder>
用数组填充Object</p><p>当组件有一个以数组作为值的Object类型的属性,在MXML中可以使用子标签表示该属性,如下所示:
<mynamespace:MyComponent>     <mynamespace:nameOfObjectProperty>        <mx:Array>             <mx:Number>94062</mx:Number>             <mx:Number>14850</mx:Number>             <mx:Number>53402</mx:Number>         </mx:Array>     </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
本例中,你初始化该Object为三元素的数字数组。
正如设置标量值数组中所述,Array元素外的<mx:Array>和</mx:Array>标签可选,可以被省略,如下所示:
<mynamespace:MyComponent>     <mynamespace:nameOfObjectProperty>         <mx:Number>94062</mx:Number>         <mx:Number>14850</mx:Number>         <mx:Number>53402</mx:Number>     </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
这项规则的唯一例外是在你指定Object属性为单个数组元素时。这种情况下,Flex不会创建包含单个元素数组的Object,而是创建一个对象,设置它为指定值。以下是二者区别:
object=[element] // 包含单元素数组的Object object=element // 等于值的object
如果你想创建单元素数组,在数组元素外包含<mx:Array>和</mx:Array>标签,如下所示:
<mynamespace:MyComponent>     <mynamespace:nameOfObjectProperty>         <mx:Array>             <mx:Number>94062</mx:Number>         </mx:Array>     </mynamespace:nameOfObjectProperty> </mynamespace:MyComponent>
填充对象数组</p><p>当组件以对象数组作为属性值时,可以在MXML中使用子标签表示属性,如下所示:
<mynamespace:MyComponent>     <mynamespace:nameOfProperty>         <mx:Array>             <mynamespace:objectType prop1="val1" prop2="val2"/>             <mynamespace:objectType prop1="val1" prop2="val2"/>             <mynamespace:objectType prop1="val1" prop2="val2"/>         </mx:Array>     </mynamespace:nameOfProperty> </mynamespace:MyComponent>
下面例子中的组件包含ListItem对象数组。每一个ListItem对象有label和data属性。
<mynamespace:MyComponent>     <mynamespace:dataProvider>         <mx:Array>             <mynamespace:ListItem label="One" data="1"/>             <mynamespace:ListItem label="Two" data="2"/>         </mx:Array>     </mynamespace:dataProvider> </mynamespace:MyComponent>
下面的例子给出了如何指定匿名对象作为dataProvider属性值:
<mynamespace:MyComponent>     <mynamespace:dataProvider>         <mx:Array>             <mx:Object label="One" data="1"/>             <mx:Object label="Two" data="2"/>         </mx:Array>     </mynamespace:dataProvider> </mynamespace:MyComponent>
正如设置标量值数组章节所述,数组元素外的<mx:Array>和</mx:Array>标签可选,可以省略,如下所示:
<mynamespace:MyComponent>     <mynamespace:dataProvider>         <mx:Object label="One" data="1"/>         <mx:Object label="Two" data="2"/>     </mynamespace:dataProvider> </mynamespace:MyComponent>
设置包含XML数据的属性</p><p>如果一个组件包含了XML数据属性,该属性值就是可以应用命名空间的XML片段。在下面的例子中,MyComponent对象的value值是XML数据:
<mynamespace:MyComponent>     <mynamespace:value xmlns:a="http://www.example.com/myschema";>         <mx:XML>             <a:purchaseorder>                 <a:billingaddress>                 ...                 </a:billingaddress>                 ...         </a:purchaseorder>     </mx:XML> </mynamespace:value> </mynamespace:MyComponent>
在MXML中设置样式和效果属性</p><p>MXML标签中的样式或效果属性和其他属性不同,因为它对应于ActionScript样式或效果,而不是ActionScript类的属性。在ActionScript使用setStyle(stylename, value)方法设置这些属性,而不是object.property=value。
在ActionScript类中使用[Style]或[Effect]元数据标签定义样式或效果属性,而不是定义为ActionScript变量或setter/getter方法。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的自定义组件中的元数据标签。
比如,在MXML设置fontFamily样式属性,如下所示:
<mx:TextArea id="myText" text="hello world" fontFamily="Tahoma"/>
该 MXML 代码等价于以下ActionScript 代码:
myText.setStyle("fontFamily", "Tahoma");
在MXML 中设置事件属性</p><p>MXML标签的事件属性允许你指定事件的事件监听器。该属性相当于在ActionScript中使用addEventListener()方法设置事件监听器。
在ActionScript类中使用[Event]元数据标签定义事件属性,而不是定义为ActionScript变量或setter/getter方法。更多信息,参见《Creating and Extending Adobe Flex 3 Components》中的子定义组件中的元数据标签
比如,你可以在MXML中设置creationComplete事件属性,代码如下所示:
<mx:TextArea id="myText" creationComplete="creationCompleteHandler()"/>
该 MXML 代码等价于以下ActionScript 代码:
myText.addEventListener("creationComplete", creationCompleteHandler);
指定URL值</p><p>某些MXML标签,比如<mx:Script>标签,有以外部文件URL为值的属性。比如,可以在<mx:Script>标签中设置source属性引用外部ActionScript文件,代替在<mx:Script>标签体内直接键入ActionScript。
注意:在<mx:Script>标签的source属性指定脚本。不要在source属性中指定ActionScript类。关于使用ActionScript类的更多信息,参见创建ActionScript组件。
MXML 支持以下URL类型:
绝对路径,如下所示:
<mx:Style source="http://www.somesite.com/mystyles.css";>
相对于运行Flex应用的Java web应用上下文根路径的运行时路径。比如:
<mx:HTTPService url="@ContextRoot()/directory/myfile.xml"/>
相对于运行Flex应用的Java web应用上下文根路径的编译时路径,如下所示:
<mx:Script source="/myscript.as"/>
相对于当前文件位置的路径,如下所示:
<mx:Script source="../myscript.as"/>
指定 RegExp 值</p><p>对于RegExp类型的属性,你可以在MXML中使用以下格式定义值:
"/pattern/flags"
pattern 在两条斜线内指定正则表达式。两条斜线均必需。
flags(可选) 指定正则表达式的任意标记。
比如,MXML组件的regExpression属性为RegExp类型。因此,可以如下设置它的值:
<mynamespace:MyComponent regExpression="/Wcat/gi"/>
或者使用子标签设置,如下所示:
<mynamespace:MyComponent>     <mynamespace:regExpression>/Wcat/gi</mynamespace:regExpression> </mynamespace:MyComponent>
正则表达式的flags部分可选,因此还可以如下指定:
<mynamespace:MyComponent regExpression="/Wcat/"/>
使用compiler 标签</p><p>编译器标签是一些不直接对应于ActionScript对象或属性的标签。下列编译器标签的命名第一个字母大写:
<mx:Binding>
<mx:Component>
<mx:Metadata>
<mx:Model>
<mx:Script>
<mx:Style>
<mx:XML>
<mx:XMLList>
下列编译器标签全是小写字母:
<mx:operation>
<mx:request>
<mx:method>
<mx:arguments>
MXML 标签规则</p><p>MXML 有以下语法要求:
任何标签中id 属性不必需。
root 标签中不能有 id 属性。
Boolean 属性只能为 true 或 false值。
<mx:Binding> 标签中source 和 destination 属性必需。
<mx:Binding> 标签不能包含 id 属性。
<mx:WebService> 标签中必须有 wsdl 值或 destination 值,但不能二者均有。
<mx:RemoteObject>标签中必须有 source值或 name值,但不能二者均有。
<mx:HTTPService> 标签中必须有 url值或 destination值,但不能二者均有。
<mx:operation>标签中 name 值必需,但不允许有相同的 name 项。
<mx:operation>标签不能包含 id 属性。
<mx:method> 标签中 name 值必需,但不允许有相同的 name 项。
<mx:method>标签不包含id 属性。</p>

- 阅读剩余部分 -

mysql_connect() 不支持 请检查 mysql 模块是否正确加载

<p>升级PHP 5.32之后模块不能正常加载了.之后卸载掉 .从新安装依然不能正常加载. 于是拿DZ的产品测试看看哪里的问题..(DZ真是好东西能检查组件.)</p><div style="page-break-after: always;"><span style="display: none;"><!--more-->& nbsp ;</span></div><p>一、 在系统的 system32(C:windowssystem32)目录下缺少libmysql.dll文件,解决方法是找到php目录下的 libmysql.dll,并将libmysql.dll复制到C: windowssystem32目录中,然后重新启动Web服务。</p><p>二、在C:windows目录下的php.ini文件中,没有将“;extension=php_mysql.dll”中的前面一个“;”去掉,所以不能使用相应功能,解决方法是打开php.ini文件找到;extension=php_mysql.dll    改成</p><p>extension=php_mysql.dll    //去掉前面的;使之生效</p><p>三、Mysql目录没有读取权限,正确的目录权限如下:</p><p>administrator   完全控制
system          完全控制
users           读取和运行+列出文件夹目录+读取
其他的用户权限全部删除,然后重启MYsql服务和Web服务
(注:以上设置无安全设置;建议修改后重启一下服务器)
重要,还要检查php.ini文件的权限,检查复制到system32里面的php文件的权限,检查php安装目录文件夹的权限.至少要有users默认权限.temp文件夹至少要有users组修改级别权限.</p><p> </p><p>但是,所有的方法都试过了,还是没能解决,于是我搜索了一下mysql_connect()不支持,</p><p>http://wenwen.soso.com/z/q141514137.htm的回答对我启发很大,</p><p>
把以下代码保存为phpinfo.php:
<?php
phpinfo();
?></p><p>放在discuz所在目录中, 用浏览器访问它. 然后在phpinfo.php显示页面中查找字符串 mysql.
如果MySQL已经安装, 并且php_mysql模块也正确装载了, 就能看到类似下面的表格:</p><p>  mysql
-------
MySQL Support  enabled
Active Persistent Links 1
Active Links  1
Client API version  5.0.37
-------
如果看不到, 而且你确定数据库已经安装了, 那么可能需要在服务器中加载libmysql.dll:
打开httpd.conf (这个是Apache的配置文件), 加入:
LoadFile "你的PHP目录/libmysql.dll"
然后重启http服务.</p><p> </p><p>我按照他说的做了之后,没能看到有mysql的信息,但是数据库确实已经运行无误。</p><p>于是搜了下“phpinfo()中没有Mysql” 结果是需要把 D:php5ext目录下的php_mysql.dll、php_mysqli.dll和上层目录中的libmysql.dll复制到system32</p><p>并将php的目录加到windows的系统路径里去,</p><p>在 Windows NT,2000,XP 和 2003 下:</p><p>进入控制面板并打开“系统”图标(开始 -> 设置 -> 控制面板 -> 系统,Windows XP/2003 中是:开始 -> 控制面板 -> 系统)</p><p>选择“高级”标签页</p><p>点击“环境变量”按钮</p><p>在“系统变量”栏中</p><p>找到 Path 这一项(可能需要向下滚动才能找到)</p><p>鼠标双击 Path 这一项</p><p>在最后加入你的 PHP 目录,包括前面的“;”(例如: ;C:php )</p><p>点击“确定”并重新启动电脑</p>

- 阅读剩余部分 -

随机文章

最近回复

分类

其它

友情连接

推广链接