yxhxj2006

常用链接

统计

最新评论

2014年12月31日 #

jQuery 插件autocomplete 应用

项目中有时会用到自动补全查询,就像Google搜索框、淘宝商品搜索功能,输入汉字或字母,则以该汉字或字母开头的相关条目会显示出来供用户选择, autocomplete插件就是完成这样的功能。

  autocomplete官网 : http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ (可下载jQuery autocomplete插件)。

  淘宝商品搜索功能 效果:

  下面来使用 autocomplete插件来实现类似效果。

1. 创建 AjaxPage.aspx 页面,在其中定义 WebMethod 方法来返回 搜索页面需要的输入框所有提示条目。 后台代码如下:

复制代码
 1 using System.Collections.Generic;
2 using System.IO;
3 using System.Runtime.Serialization.Json;
4 using System.Web.Services;
5
6 public partial class AjaxPage : System.Web.UI.Page
7 {
8 [WebMethod]
9 public static string GetAllHints()
10 {
11 Dictionary<string, string> data = new Dictionary<string, string>();
12 data.Add("苹果4代iphone正品", "21782");
13 data.Add("苹果4代 手机套", "238061");
14 data.Add("苹果4", "838360");
15 data.Add("苹果皮", "242721");
16 data.Add("苹果笔记本", "63348");
17 data.Add("苹果4s", "24030");
18 data.Add("戴尔笔记本", "110105");
19 data.Add("戴尔手机", "18870");
20 data.Add("戴尔键盘", "30367");
21
22 DataContractJsonSerializer serializer = new DataContractJsonSerializer(data.GetType());
23
24 using (MemoryStream ms = new MemoryStream())
25 {
26 serializer.WriteObject(ms, data);
27 return System.Text.Encoding.UTF8.GetString(ms.ToArray());
28 }
29 }
30 }
复制代码

  注:该方法返回的数据格式为json字符串。

2. 创建搜索页面 Index.aspx, 前台代码如下:

复制代码
 1 <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Index.aspx.cs" Inherits="_Default" %>
2
3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml">
6 <head runat="server">
7 <title></title>
8 <link rel="Stylesheet" href="Styles/jquery.autocomplete.css" />
9 <script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
10 <script type="text/javascript" src="Scripts/jquery.autocomplete.js"></script>
11 <script type="text/javascript">
12 var v = 1;
13 $(document).ready(function () {
14 $.ajax({
15 type: "POST",
16 contentType: "application/json",
17 url: "AjaxPage.aspx/GetAllHints",
18 data: "{}",
19 dataType: "json",
20 success: function (msg) {
21 var datas = eval('(' + msg.d + ')');
22 $("#txtIput").autocomplete(datas, {
23 formatItem: function (row, i, max) {
24 return "<table width='400px'><tr><td align='left'>" + row.Key + "</td><td align='right'><font style='color: #009933; font-family: 黑体; font-style: italic'>约" + row.Value + "个宝贝</font>&nbsp;&nbsp;</td></tr></table>";
25 },
26 formatMatch: function(row, i, max){
27 return row.Key;
28 }
29 });
30 }
31 });
32 });
33 </script>
34 </head>
35 <body>
36 <form id="form1" runat="server">
37 <div>
38 <center>
39 <asp:TextBox ID="txtIput" runat="server" Width="400px"></asp:TextBox>
40 </center>
41 </div>
42 </form>
43 </body>
44 </html>
复制代码

  实现效果如下:

3. autocomplete 参数说明

* minChars (Number)
    在触发autoComplete前用户至少需要输入的字符数.Default: 1,如果设为0,在输入框内双击或者删除输入框内内容时显示列表
* width (Number)
    指定下拉框的宽度. Default: input元素的宽度
* max (Number)
    autoComplete下拉显示项目的个数.Default: 10
* delay (Number)
    击键后激活autoComplete的延迟时间(单位毫秒).Default: 远程为400 本地10
* autoFill (Boolean)
    要不要在用户选择时自动将用户当前鼠标所在的值填入到input框. Default: false
* mustMatch (Booolean)
    如果设置为true,autoComplete只会允许匹配的结果出现在输入框,所有当用户输入的是非法字符时将会得不到下拉框.Default: false
* matchContains (Boolean)
    决定比较时是否要在字符串内部查看匹配,如ba是否与foo bar中的ba匹配.使用缓存时比较重要.不要和autofill混用.Default: false
* selectFirst (Boolean)
    如果设置成true,在用户键入tab或return键时autoComplete下拉列表的第一个值将被自动选择,尽管它没被手工选中(用键盘或鼠标).当然如果用户选中某个项目,那么就用用户选中的值. Default: true
* cacheLength (Number)
    缓存的长度.即对从数据库中取到的结果集要缓存多少条记录.设成1为不缓存.Default: 10
* matchSubset (Boolean)
    autoComplete可不可以使用对服务器查询的缓存,如果缓存对foo的查询结果,那么如果用户输入foo就不需要再进行检索了,直接使用缓存.通常是打开这个选项以减轻服务器的负担以提高性能.只会在缓存长度大于1时有效.Default: true
* matchCase (Boolean)
    比较是否开启大小写敏感开关.使用缓存时比较重要.如果你理解上一个选项,这个也就不难理解,就好比foot要不要到FOO的缓存中去找.Default: false
* multiple (Boolean)
    是否允许输入多个值即多次使用autoComplete以输入多个值. Default: false
* multipleSeparator (String)
    如果是多选时,用来分开各个选择的字符. Default: ","
* scroll (Boolean)
    当结果集大于默认高度时是否使用卷轴显示 Default: true
* scrollHeight (Number)
    自动完成提示的卷轴高度用像素大小表示 Default: 180  
* formatItem (Function)
    为每个要显示的项目使用高级标签.即对结果中的每一行都会调用这个函数,返回值将用LI元素包含显示在下拉列表中. Autocompleter会提供三个参数(row, i, max): 返回的结果数组, 当前处理的行数(即第几个项目,是从1开始的自然数), 当前结果数组元素的个数即项目的个数. Default: none, 表示不指定自定义的处理函数,这样下拉列表中的每一行只包含一个值.
* formatResult (Function)
    和formatItem类似,但可以将将要输入到input文本框内的值进行格式化.同样有三个参数,和formatItem一样.Default: none,表示要么是只有数据,要么是使用formatItem提供的值.
* formatMatch (Function)
    对每一行数据使用此函数格式化需要查询的数据格式. 返回值是给内部搜索算法使用的. 参数值row
* extraParams (Object)
    为后台(一般是服务端的脚本)提供更多的参数.和通常的作法一样是使用一个键值对对象.如果传过去的值是{ bar:4 },将会被autocompleter解析成my_autocomplete_backend.php?q=foo&bar=4 (假设当前用户输入了foo). Default: {}
* result (handler)
    此事件会在用户选中某一项后触发,参数为:
    event: 事件对象. event.type为result.
    data: 选中的数据行.
    formatted:formatResult函数返回的值
    例如:
    $("#singleBirdRemote").result(function(event, data, formatted) {
        //如选择后给其他控件赋值,触发别的事件等等
    });

 

posted @ 2016-06-17 17:54 奋斗成就男人 阅读(272) | 评论 (0)编辑 收藏

防止重复登录请求

过页头生成Token,进行请求验证,解决Ajax请求安全问题。目前为止我做的最多的防止ajax请求攻击的就是添加验证码、添加随机Token,限制同一请求在规定时间内的最大请求数。

下面重点说说添加随机Token限制:
token是为了防止表单重复提交,token 原理大致为:

1:显示表单的那个 action 中使用 createToken() 生成一个随机的 token值,并存放在服务端(session或者cache中),并且传递一份到页面中

2:表单页面使用一个隐藏表单域获取后端传过来的 token值,该表单页面提交时会将此 token 值一同提交到后端

3:在表单页面提交到的 actioin 中使用 validateToken() 将服务端与表单隐藏域中的 token 值进行对比,如果服务端存在 token值并且与表单提交过来的值相等,证明是第一次提交。

4:每次校验过后服务端的 token 值会立即被清除,所以当用户重复提交时,后面的提交校验都再也无法通过。从而实现了防止重复提交的功能,validateToken 是在 synchronized 块中执行的保障了多线程下的安全性。

    token 会优先存入 me.setTokenCache(ITokenCache) 指定的 TokenCache 中,如果未指定则默认使用 session 来存放

但是这种机制是有问题的,比如我是用ajax提交表单,提交完成以后表单页面并不刷新,然后我修改了部分数据以后再次提交页面,那么token还是之前的那个token,后台会以为这个为重复提交不能通过校验,那么请求就不能完成,数据无法得到正确的处理。我认为合理的机制应该是这样的:

1:显示表单的那个 action 中使用 createToken() 生成一个随机的 token值,并且传递一份到页面中

2:表单页面使用一个隐藏表单域获取后端传过来的 token值,该表单页面提交时会将此 token 值一同提交到后端

3:将提交过来的token值放入session或者cache中,然后执行controller中的代码,代码全部执行完以后,再把存入session或cache中的token值删除掉;验证用户是否为重复提交只需要验证提交过来的token是否存在于session或cache中,有则为重复提交,无则为正常提交。

4:该逻辑应该可以写成一个Interceptor,在需要的地方加上,或者直接设为全局拦截器都是可以的,简单,快捷;

posted @ 2015-12-03 16:03 奋斗成就男人 阅读(485) | 评论 (0)编辑 收藏

在Java中直接调用js代码

JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码。

在Java中直接调用js代码

不能调用浏览器中定义的js函数,会抛出异常提示ReferenceError: “alert” is not defined。

 
package com.sinaapp.manjushri; 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;   /**  * 直接调用js代码  */
public class ScriptEngineTest {    
public static void main(String[] args) { 
  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("javascript");
     try{                engine.eval("var a=3; var b=4;print (a+b);");           // engine.eval("alert(\"js alert\");");    // 不能调用浏览器中定义的js函数 // 错误,会抛出alert引用不存在的异常
 }catch(ScriptException e){   e.printStackTrace();  }  }    }

输出结果:7

在Java中绑定js变量

在调用engine.get(key);时,如果key没有定义,则返回null

 
package com.sinaapp.manjushri;     import javax.script.Bindings;   import javax.script.ScriptContext;   import javax.script.ScriptEngine;   import javax.script.ScriptEngineManager;   import javax.script.ScriptException;     public class ScriptEngineTest2 {    public static void main(String[] args) {    ScriptEngineManager manager = new ScriptEngineManager();    ScriptEngine engine = manager.getEngineByName("javascript");    engine.put("a", 4);    engine.put("b", 3);    Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);   try {                          // 只能为Double,使用Float和Integer会抛出异常      Double result = (Double) engine.eval("a+b");         System.out.println("result = " + result);     engine.eval("c=a+b");      Double c = (Double)engine.get("c");      System.out.println("c = " + c);         } catch (ScriptException e) {     e.printStackTrace();         }      }   }

输出:
result = 7.0
c = 7.0

在Java中调用js文件中的function,传入调用参数,并获取返回值

js文件中的merge函数将两个参数a,b相加,并返回c。

 
// expression.js 
function merge(a, b) { 
 c = a * b; 
 return c; 
}

在Java代码中读取js文件,并参数两个参数,然后回去返回值。

 
package com.sinaapp.manjushri;     import java.io.FileReader;    import javax.script.Invocable;   import javax.script.ScriptEngine;   import javax.script.ScriptEngineManager;    /**  * Java调用并执行js文件,传递参数,并活动返回值  *   * @author manjushri  */   public class ScriptEngineTest {      public static void main(String[] args) throws Exception {    ScriptEngineManager manager = new ScriptEngineManager();    ScriptEngine engine = manager.getEngineByName("javascript");       String jsFileName = "expression.js";   // 读取js文件     FileReader reader = new FileReader(jsFileName);   // 执行指定脚本    engine.eval(reader);     if(engine instanceof Invocable) {     Invocable invoke = (Invocable)engine;    // 调用merge方法,并传入两个参数      // c = merge(2, 3);      Double c = (Double)invoke.invokeFunction("merge", 2, 3);      System.out.println("c = " + c);    }     reader.close();      } }

输出结果:
c = 5.0


java调用脚本语言笔记(jython,jruby,groovy)

 有两种方法
1.java se 6以后实现了jsr 223规范
java代码:

[java]
  1. ScriptEngineManager factory = new ScriptEngineManager();  
  2. ScriptEngineManager scriptEngine = factory.getEngineByName("javascript");//或者"js"  
  3. scriptEngine.eval(code);//执行一段脚本,code是js代码  


 很方便调用脚本

2.可以使用脚本语方本身提供的与java的集成手段

jython集成
使用jsr223:
前提下载jython的包,已实现jsr223
(建议在官网上下载,在安装目录下有jython.jar,http://repo2.maven.org/maven2/org/python/jython/2.5.0/ 这里也有,但是这个包里没有jsr223的实现,看包下存不存在org.python.jsr223)

[java]
  1. ScriptEngineManager factory = new ScriptEngineManager();  
  2. ScriptEngineManager scriptEngine = factory.getEngineByName("python");//或者"jython"  
  3. scriptEngine.eval(code);  


使用PythonInterpreter,可以调用exec(String code)方法:

[java]
  1. PythonInterpreter interpreter = new PythonInterpreter();  
  2. interpreter.exec(code);  

访问数据库
使用jdbc:

[python] 
  1. from oracle.jdbc.driver import OracleDriver  
  2. from java.sql import DriverManager  
  3.   
  4. username = 'hr'  
  5. password = '123456'  
  6. url = 'jdbc:oracle:thin:@localhost:1521:XE'  
  7. driver = OracleDriver()  
  8. DriverManager.registerDriver(driver)  
  9. conn = DriverManager.getConnection(url, username, password)  
  10. stmt = conn.createStatement()  
  11. sql = "select salary from EMPLOYEES t where t.salary<2300"  
  12. rs = stmt.executeQuery(sql)  
  13. while (rs.next()):  
  14.  print rs.getInt('salary')  
  15. rs.close()  
  16. stmt.close()  


 结果:
2200
2100
2200

使用zxJDBC :

[python] 
  1. from com.ziclix.python.sql import zxJDBC  
  2.   
  3. url = 'jdbc:oracle:thin:@localhost:1521:XE'  
  4. username = 'hr'  
  5. password = '123456'  
  6. driverName = 'oracle.jdbc.driver.OracleDriver'  
  7. mysqlConn = zxJDBC.connect(url,username, password,driverName)  
  8. cursor = mysqlConn.cursor()       
  9. cursor.execute("select last_name from EMPLOYEES t where t.salary<2300");  
  10. #print cursor.fetchone()  
  11. list = cursor.fetchall()  
  12. for record in list:  
  13.     print "name:"+record[0]  
  14. #print cursor.description[0]  
  15. #print cursor.description[1]  


 结果:
name:麦克
name:Olson
name:Philtanker

从数据库中查出的中文内容正常的。
而在代码里面的中文全部是乱码或抛异常,未解决。

与jruby集成
使用jsr223:Java代码

[java]
  1. ScriptEngineManager factory = new ScriptEngineManager();  
  2. ScriptEngineManager scriptEngine = factory.getEngineByName("jruby");//或者"ruby"  
  3. scriptEngine.eval(code);  

 访问数据库

Ruby代码

[ruby] 
  1. require 'java'  
  2.   
  3. module JavaLang  
  4.   include_package "java.lang"  
  5. end  
  6.   
  7. module JavaSql  
  8.   include_package 'java.sql'  
  9. end  
  10.   
  11. begin  
  12.  username = 'hr'  
  13.  password = '123456'  
  14.  url = 'jdbc:oracle:thin:@localhost:1521:XE'  
  15.  driverName = 'oracle.jdbc.driver.OracleDriver'  
  16.  JavaLang::Class.forName(driverName).newInstance  
  17.  conn = JavaSql::DriverManager.getConnection(url, username, password)  
  18.  stmt = conn.createStatement  
  19.  sql = "select last_name from EMPLOYEES t where t.salary<2300"  
  20.  rs = stmt.executeQuery(sql)  
  21.  while (rs.next) do  
  22.   puts "名字:"+rs.getString("last_name")  
  23.  end  
  24.  rs.close  
  25.  stmt.close  
  26.  conn.close()  
  27. rescue JavaLang::ClassNotFoundException  
  28.  puts "ClassNotFoundException"  
  29. rescue JavaSql::SQLException  
  30.  puts "SQLException"  
  31. end  


 

 结果:
名字:楹﹀厠
名字:Olson
名字:Philtanker

 

从数据库中查出的中文内容为乱码的。
而在代码里面的中文正常。

 

与groovy集成
使用jsr223:

Java代码

[java] 
  1. ScriptEngineManager factory = new ScriptEngineManager();  
  2. ScriptEngineManager scriptEngine = factory.getEngineByName("groovy");//或者"Groovy"  
  3. scriptEngine.eval(code);  


 使用GroovyShell:

Java代码

[java] 
  1. GroovyShell shell = new GroovyShell();  
  2. Script script = shell.parse(code);  
  3. Object result = script.run();  


访问数据库

Groovy代码

 

  1. import groovy.sql.Sql  
  2.   
  3. def username = 'hr'  
  4. def password = '123456'  
  5. def url = 'jdbc:oracle:thin:@localhost:1521:XE'  
  6. def driverName = 'oracle.jdbc.driver.OracleDriver'  
  7. def sql = Sql.newInstance(url, username, password, driverName)  
  8.   
  9. sql.eachRow("select last_name from EMPLOYEES t where t.salary<2300") {  
  10.  println "名字:${it.last_name}"  
  11. }  

结果:
名字:麦克
名字:Olson
名字:Philtanker

 

在使用groovy过程中碰到了一个异常
Exception in thread "main" java.lang.VerifyError: (class: groovy/runtime/metaclass/java/util/ArrayListMetaClass, method: super$2$invokeMethod signature: (Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;ZZ)Ljava/lang/Object;) Illegal use of nonvirtual function call
这个异常解决花了很长时间
是因为在原来项目中存在json-lib-2.1.jar(有可能名称为json-lib-2.1-jdk15.jar),这个包是用来处理json的,与groovy1.7.5存在冲突,更新为json-lib-2.3.jar即可
(json-lib里有一些groovy运行时处理的内容)

posted @ 2015-11-19 00:25 奋斗成就男人 阅读(2912) | 评论 (0)编辑 收藏

Java导入证书的问题(PKIX:unable to find valid certification path to requested target 的问题)

这两天Java服务器上忽然遇到这样的异常:

avax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

问题的根本是:

缺少安全证书时出现的异常。

解决问题方法:

将你要访问的webservice/url....的安全认证证书导入到客户端即可。


以下是获取安全证书的一种方法,通过以下程序获取安全证书:

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
*/

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class InstallCert {

    public static void main(String[] args) throws Exception {
        String host;
        int port;
        char[] passphrase;
        if ((args.length == 1) || (args.length == 2)) {
            String[] c = args[0].split(":");
            host = c[0];
            port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
            String p = (args.length == 1) ? "changeit" : args[1];
            passphrase = p.toCharArray();
        } else {
            System.out
                    .println("Usage: java InstallCert <host>[:port] [passphrase]");
            return;
        }

        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP + "lib"
                    + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                .getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(nullnew TrustManager[] { tm }, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out
                .println("Opening connection to " + host + ":" + port + "");
        SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));

        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println(" " + (i + 1) + " Subject "
                    + cert.getSubjectDN());
            System.out.println("   Issuer  " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println("   sha1    " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println("   md5     " + toHexString(md5.digest()));
            System.out.println();
        }

        System.out
                .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();

        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out
                .println("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }

}

编译InstallCert.java,然后执行:java InstallCert hostname,比如:
java InstallCert www.twitter.com
会看到如下信息:

java InstallCert www.twitter.com
Loading KeyStore /usr/java/jdk1.6.0_16/jre/lib/security/cacerts
Opening connection to www.twitter.com:443
Starting SSL handshake

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1476)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:846)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:815)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1038)
    at InstallCert.main(InstallCert.java:63)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)
    at sun.security.validator.Validator.validate(Validator.java:203)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
    at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:158)
    at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:839)
     7 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
     13 more

Server sent 2 certificate(s):

 1 Subject CN=www.twitter.com, O=example.com, C=US
   Issuer  CN=Certificate Shack, O=example.com, C=US
   sha1    2e 7f 76 9b 52 91 09 2e 5d 8f 6b 61 39 2d 5e 06 e4 d8 e9 c7 
   md5     dd d1 a8 03 d7 6c 4b 11 a7 3d 74 28 89 d0 67 54 

 2 Subject CN=Certificate Shack, O=example.com, C=US
   Issuer  CN=Certificate Shack, O=example.com, C=US
   sha1    fb 58 a7 03 c4 4e 3b 0e e3 2c 40 2f 87 64 13 4d df e1 a1 a6 
   md5     72 a0 95 43 7e 41 88 18 ae 2f 6d 98 01 2c 89 68 

Enter certificate to add to trusted keystore or 'q' to quit: [1]


输入1,回车,然后会在当前的目录下产生一个名为“ssecacerts”的证书。

将证书拷贝到$JAVA_HOME/jre/lib/security目录下,或者通过以下方式:
System.setProperty("javax.net.ssl.trustStore", "你的jssecacerts证书路径");



注意:因为是静态加载,所以要重新启动你的Web Server,证书才能生效。


试了以上的方法,后来发现还不行。最后突然心血来潮:我把Myeclipse关闭,直接启动Tomcat,然后运行,居然就可以了。具体原因没有找到。估计是
我的Myeclipse引用的JDK引用不对。后来就没有具体找原因了。

posted @ 2015-10-30 15:06 奋斗成就男人 阅读(1394) | 评论 (0)编辑 收藏

常用的MySQL语句写法

MySQLSQL语句写法,除了那些基本的之外,还有一些也算比较常用的,这里记录下来,以便以后查找。
    好记性不如烂笔头,这话说的太有道理了,一段时间不写它,还真容易忘记。大家不要纠结这些SQL语句包含的业务或是其它问题,本文只是一篇笔记而已。

    将数据从T1表导入到T2
INSERT INTO T2 (C1,C2) SELECT C1,C2 FROM T1 [WHERE C1 = XX AND C2 = XX ORDER BY C1]

    使用T2表的NAME来更新T1表的NAME
UPDATE T1 AS A, T2 AS B SET A.NAME = B.NAME WHERE A.TID = B.ID

    两表的关联更新
UPDATE T_ROLE_USER AS A,
 (
    SELECT
        ID
    FROM
        T_USER
    WHERE
        DEPARTID IN (
            SELECT
                ID
            FROM
                T_DEPART
            WHERE
                LENGTH(ORG_CODE) = 9
        )
AS B
SET A.ROLEID = '123456'
WHERE
    A.USERID = B.ID

    自己和自己关联更新
UPDATE T_DEPART AS A,
 (
    SELECT
        ID,
        SUBSTRING(ORG_CODE, 16) ORG_CODE
    FROM
        T_DEPART
    WHERE
        LENGTH(ORG_CODE) = 8
    AND PARENT_DEPART_ID IS NOT NULL
AS B
SET A.PARENT_DEPART_ID = B.ID
WHERE
    SUBSTRING(A.ORG_CODE, 16= B.ORG_CODE

    两表关联删除,将删除两表中有关联ID并且T2NAME为空的两表记录
DELETE A,B FROM T1 AS A LEFT JOIN T2 AS B ON A.TID = B.ID WHERE B.NAME IS NULL

    将统计结果插入到表
INSERT INTO SE_STAT_ORG (
    RECORD_DATE,
    ORG_ID,
    ORG_NAME,
    SIGN_CONT_COUNT,
    SIGN_ARRI_CONT_COUNT,
    SIGN_CONT_MONEY,
    SIGN_ARRI_CONT_MONEY,
    TOTAL_ARRI_CONT_COUNT,
    TOTAL_ARRI_MONEY,
    PUBLISH_TOTAL_COUNT,
    PROJECT_COUNT
SELECT
    *
FROM
    (
        SELECT
            '2012-06-09' RECORD_DATE,
            PARENT_ORG_ID,
            PARENT_ORG_NAME,
            SUM(SIGN_CONT_COUNT) SIGN_CONT_COUNT,
            SUM(SIGN_ARRI_CONT_COUNT) SIGN_ARRI_CONT_COUNT,
            SUM(SIGN_CONT_MONEY) SIGN_CONT_MONEY,
            SUM(SIGN_ARRI_CONT_MONEY) SIGN_ARRI_CONT_MONEY,
            SUM(TOTAL_ARRI_CONT_COUNT) TOTAL_ARRI_CONT_COUNT,
            SUM(TOTAL_ARRI_MONEY) TOTAL_ARRI_MONEY,
            SUM(PUBLISH_TOTAL_COUNT) PUBLISH_TOTAL_COUNT,
            SUM(PROJECT_COUNT) PROJECT_COUNT,
        FROM SE_STAT_USER
        WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
        GROUP BY PARENT_ORG_ID
    ) M

    三表关联更新
UPDATE SE_STAT_USER A,
 (
    SELECT
        USER_ID,
        SUM(INVEST_ORG_COUNT + FINANCIAL_ORG_COUNT + INTERMEDIARY_ORG_COUNT + ENTERPRISE_COUNT) AS COMMON_COUNT
    FROM SE_STAT_USER
    WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
    GROUP BY USER_ID
) B,
 (
    SELECT
        USER_ID,
        SUM(ESTABLISH_COUNT + STOCK_COUNT + MERGER_COUNT + ACHIEVE_COUNT) AS PROJECT_COUNT
    FROM SE_STAT_USER
    WHERE DATE_FORMAT(RECORD_DATE, '%Y-%m-%d'= '2012-06-09'
    GROUP BY USER_ID
) C
SET A.COMMON_COUNT = B.COMMON_COUNT, A.PROJECT_COUNT = C.PROJECT_COUNT
WHERE A.USER_ID = B.USER_ID
AND A.USER_ID = C.USER_ID
AND DATE_FORMAT(A.RECORD_DATE, '%Y-%m-%d'= '2012-06-09'

    带条件的关联更新
UPDATE SE_STAT_USER A,
 (
    SELECT
        P.CHANNEL,
        COUNT(P.CONT_ID) AS CONT_COUNT,
        C.CUST_MGR_ID
    FROM
        (
            SELECT
                CHANNEL,
                CONT_ID
            FROM SK_PROJECT
            WHERE PROJECT_STATUS = 6
            AND DATE_FORMAT(AUDIT_TIME, '%Y-%m-%d'= '2012-06-11'
        ) p
    INNER JOIN SE_CONTRACT C ON P.CONT_ID = C.CONT_ID
    GROUP BY P.CHANNEL, C.CUST_MGR_ID
) B
SET
    A.STOCK_COUNT = CASE WHEN B.CHANNEL = 2 THEN B.CONT_COUNT ELSE 0 END,
    A.ESTABLISH_COUNT = CASE WHEN B.CHANNEL = 3 THEN B.CONT_COUNT ELSE 0 END,
    A.ACHIEVE_COUNT = CASE WHEN B.CHANNEL = 4 THEN B.CONT_COUNT ELSE 0 END
    A.BRAND_COUNT = CASE WHEN B.CHANNEL = 5 THEN B.CONT_COUNT ELSE 0 END,
    A.MERGER_COUNT = CASE WHEN B.CHANNEL = 6 THEN B.CONT_COUNT ELSE 0 END
WHERE
    A.USER_ID = B.CUST_MGR_ID
AND DATE_FORMAT(A.RECORD_DATE, '%Y-%m-%d'= '2012-06-11'

    加索引
ALTER TABLE PROJECT ADD INDEX INDEX_USER_ID (USER_ID),
        ADD INDEX INDEX_PROJECT_STATUS (PROJECT_STATUS);

    删除列
ALTER TABLE PROJECT DROP COLUMN PROJECT_STATUS,
        DROP COLUMN EXPECT_RETURN,DROP COLUMN CURRENCY;

    增加列
ALTER TABLE PROJECT 
        ADD COLUMN DICT_ID INT DEFAULT NULL COMMENT 'xxx' AFTER PROJECT_SITE,
        ADD COLUMN INTRODUCE TEXT DEFAULT NULL COMMENT 'xx' AFTER DICT_ID,
        ADD COLUMN STAGE INT DEFAULT NULL COMMENT 'xx' AFTER ID,
        ADD COLUMN ATTACH_URI VARCHAR(8DEFAULT NULL COMMENT 'xxx' AFTER INTRODUCE;

    修改列,一般用MODIFY修改数据类型,CHANGE修改列名
ALTER TABLE PROJECT CHANGE DICT_ID DICT_ID1 INT NOT NULL,
        MODIFY PROJECT_STATUS TINYINT NOT NULL COMMENT 'xxx';

posted @ 2015-08-09 23:31 奋斗成就男人 阅读(384) | 评论 (0)编辑 收藏

程序员必看的书

做为一名程序员,如果你只顾得写代码,那是不行的,要抽出一下时间来丰富自己的知识,多看看书,在这里我将为程序员们推荐一些不错的书。能够给程序员们带来帮助。

大数据时代

5487a5bd00010d2903120426

《大数据时代》是国外大数据研究的先河之作,本书作者维克托•迈尔•舍恩伯格被誉为"大数据商业应用第一人",拥有在哈佛大学、牛津大学、耶鲁大学和新加坡国立大学等多个互联网研究重镇任教的经历,早在2010年就在《经济学人》上发布了长达14页对大数据应用的前瞻性研究。

维克托•迈尔•舍恩伯格在书中前瞻性地指出,大数据带来的信息风暴正在变革我们的生活、工作和思维,大数据开启了一次重大的时代转型,并用三个部分讲述了大数据时代的思维变革、商业变革和管理变革。

维克托最具洞见之处在于,他明确指出,大数据时代最大的转变就是,放弃对因果关系的渴求,而取而代之关注相关关系。也就是说只要知道"是什么",而不需要知道"为什么"。这就颠覆了千百年来人类的思维惯例,对人类的认知和与世界交流的方式提出了全新的挑战。

 淘宝技术这十年

5487a5c800013dae03030438

《淘宝技术这十年》内容简介:任何网站的发展都不是一蹴而就的。它在发展过程中会遇到各种各样的问题和业务带来的压力。正是这些问题和压力推动着技术的进步和发展,而技术的发展反过来又会促进业务的更大提升。如今淘宝网的流量排名已是全球前15名、国内前3名,其系统服务器也从一台发展到万台以上。

《淘宝技术这十年》从工程师的角度讲述淘宝这个超大规模互联网系统的成长历程,及其所有主动和被动的技术变革的前因后果。书中有幕后故事、产品经验、架构演进、技术启蒙,也有大牛成长、业内八卦、失败案例、励志故事。《淘宝技术这十年》文风流畅,有技术人员特有的幽默感;内容积极正面,有现场感,全部是作者亲身经历。

白帽子讲Web安全

5487a7b90001fa2303030438

《白帽子讲Web安全》内容简介:在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷。如何才能更好地保护我们的数据?《白帽子讲Web安全》将带你走进Web安全的世界,让你了解Web安全的方方面面。黑客不再变得神秘,攻击技术原来我也可以会,小网站主自己也能找到正确的安全道路。大公司是怎么做安全的,为什么要选择这样的方案呢?你能在《白帽子讲Web安全》中找到答案。详细的剖析,让你不仅能"知其然",更能"知其所以然"。

重构:改善既有代码的设计

5487a7c400010cce04000400

《重构:改善既有代码的设计》清晰地揭示了重构的过程,解释了重构的原理和最佳实践方式,并给出了何时以及何地应该开始挖掘代码以求改善。书中给出了70多个可行的重构,每个重构都介绍了一种经过验证的代码变换手法的动机和技术。《重构:改善既有代码的设计》提出的重构准则将帮助你一次一小步地修改你的代码,从而减少了开发过程中的风险。

《重构:改善既有代码的设计》适合软件开发人员、项目管理人员等阅读,也可作为高等院校计算机及相关专业师生的参考读物。

代码整洁之道

5487a7cf000167fd03240408

软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关。这一点,无论是敏捷开发流派还是传统开发流派,都不得不承认。《代码整洁之道》提出一种观念:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。

作为编程领域的佼佼者,《代码整洁之道》作者给出了一系列行之有效的整洁代码操作实践。这些实践在《代码整洁之道》中体现为一条条规则(或称"启示"),并辅以来自现实项目的正、反两面的范例。只要遵循这些规则,就能编写出干净的代码,从而有效提升代码质量。

《代码整洁之道》阅读对象为一切有志于改善代码质量的程序员及技术经理。书中介绍的规则均来自作者多年的实践经验,涵盖从命名到重构的多个编程方面,虽为一"家"之言,然诚有可资借鉴的价值。

设计模式之禅 (第2版)


549ccdfa00018b6503630363

  本书是设计模式领域公认的3本经典著作之一,"极具趣味,容易理解,但讲解又极为严谨和透彻"是本书的写作风格和方法的最大特点。第1版2010年出版,畅销至今,广受好评,是该领域的里程碑著作。深刻解读6大设计原则和28种设计模式的准确定义、应用方法和最佳实践,全方位比较各种同类模式之间的异同,详细讲解将不同的模式组合使用的方法。第2版在第1版的基础上有两方面的改进,一方面结合读者的意见和建议对原有内容中的瑕疵进行了修正和完善,另一方面增加了4种新的设计模式,希望这一版能为广大程序员们奉上一场更加完美的设计模式盛宴!

程序员修炼之道

549cce040001ee3b03150420

  《程序员修炼之道》由一系列的独立的部分组成,涵盖的主题从个人责任、职业发展,直到用于使代码保持灵活、并且易于改编和复用的各种架构技术。利用许多富有娱乐性的奇闻轶事、有思想性的例子以及有趣的类比,全面阐释了软件开发的许多不同方面的最佳实践和重大陷阱。无论你是初学者,是有经验的程序员,还是软件项目经理,本书都适合你阅读。

平台战略:正在席卷全球的商业模式革命

549cce0e00012ad003120426

《平台战略:正在席卷全球的商业模式革命》内容简介:平台商业模式的精髓,在于打造一个完善的、成长潜能强大的"生态圈"。它拥有独树一帜的精密规范和机制系统,能有效激励多方群体之间互动,达成平台企业的愿景。纵观全球许多重新定义产业架构的企业,我们往往就会发现它们成功的关键——建立起良好的"平台生态圈",连接两个以上群体,弯曲、打碎了既有的产业链。

平台生态圈里的一方群体,一旦因为需求增加而壮大,另一方群体的需求也会随之增长。如此一来,一个良性循环机制便建立了,通过此平台交流的各方也会促进对方无限增长。而通过平台模式达到战略目的,包括规模的壮大和生态圈的完善,乃至对抗竞争者,甚至是拆解产业现状、重塑市场格局。

互联网创业启示录

549cce170001475203030438

《互联网创业启示录》是一部互联网公司的创业指南,内容涉及网站创业的现状和机遇、创业公司价值、平台选择、工具和群组、资金的筹集、管理和盈利、社会化媒体环境、行动执行管理、开发人员方法论和工作效率、创始人的角色等方面,既有纲领和指导性理论,又有具体操作方法。书中大量对互联网创业成功人士的访谈介绍,以及创业公司的成功案例,更可以作为初次创业者的良好借鉴。

《互联网创业启示录》主要写给想自己创业的程序员,但同样适合非技术人员,适合网络创业者、大学生创业者、网络营销人员及一切有志创业者。做网络不一定要懂技术,互联网的成功是可以借鉴和延伸的!

程序员健康指南

549cce2600015a5003600369

本书是为程序员量身制作的健康指南,针对头痛、眼部疲劳、背部疼痛和手腕疼痛等常见的问题,简要介绍了其成因、测试方法,并列出了每天的行动计划,从运动、饮食等方面给出详细指导,帮助程序员在不改变工作方式的情况下轻松拥有健康。

本书适合程序员、长期伏案工作的其他人群以及所有关心健康的人士阅读。

结网@改变世界的互联网产品经理

54aa4f680001268603060435

本书以如何创建、发布、推广互联网产品为主线,介绍了互联网产品经理的工作内容以及应对每一部分工作所需的方法和工具。为用户创造价值是产品经理的第一要务,产品经理的工作是围绕用户及具体任务展开的,本书丰富的案例和透彻的分析道出了从发现用户到最终满足用户这一过程背后的玄机。

本书面向现在正在从事及未来将要从事互联网相关工作的创业者和产品经理,也可以作为互联网产品策划人员或相关专业学生的参考书。新版完善了各章节,增加了优雅降级等内容,读者也可从中更深地去感受一名产品经理的感悟。

程序员面试逻辑题解析

54aa4f7800016ca403240408

程序员面试逻辑题解析》共分为3个部分。第一部分从有趣且锻炼头脑的谜题入手,继而给出解题思路和详细答案,更有"热身问题"给大家提供充分的思考空间。第二部分综合了不同类型的谜题,如数独、调度问题及概率题等。神秘的第三部分带领大家不断历险,开动脑筋,解决大量密码及银行账户等方面的问题。几十道简洁的小谜题不仅充分锻炼了我们的思维方式,更为提高面试成功率奠定了基础。

    《程序员面试逻辑题解析》不仅适合程序员阅读,更是谜题爱好者的饕餮盛宴。

程序员,你伤不起

54aa4f8d000171b703060435

本书是作者博客文章的精选集。是作者作为老牌程序员、现在的IT 创业者15 年软件开发生涯的心路历程和经验总结。涉及程序人生、开发经验、职业规划、创业心得。对任何的软件开发者和IT 从业人员都有借鉴价值。作者语言风趣幽默,读起来津津有味。字里行间充满了不屈不挠的码农正能量。

像程序员一样思考

54aa4f9800013e1e03270405

编程的真正挑战不是学习一种语言的语法,而是学习创造性地解决问题,从而构建美妙的应用。《像程序员一样思考》分析了程序员解决问题的方法,并且教授你其他图书所忽略的一种能力,即如何像程序员一样思考。

全书分为8章。第1章通对几个经典的算法问题切入,概括了问题解决的基本技巧和步骤。第2章通过实际编写C++代码来解决几个简单的问题,从而让读者进一步体会到问题解决的思路和应用。第3到7章是书中的主体部分,分别探讨了用数组、指针和动态内存、类、递归和代码复用来解决问题的途径和实际应用。最后,第8章从培养程序员思维的角度,进行了总结和概括,告诉读者如何才能像程序员一样思考。

编写可读代码的艺术

54aa4fbf0001a7c103180417

细节决定成败,思路清晰、言简意赅的代码让程序员一目了然;而格式凌乱、拖沓冗长的代码让程序员一头雾水。除了可以正确运行以外,优秀的代码必须具备良好的可读性,编写的代码要使其他人能在最短的时间内理解才行。本书旨在强调代码对人的友好性和可读性。

本书关注编码的细节,总结了很多提高代码可读性的小技巧,看似都微不足道,但是对于整个软件系统的开发而言,它们与宏观的架构决策、设计思想、指导原则同样重要。编码不仅仅只是一种技术,也是一门艺术,编写可读性高的代码尤其如此。如果你要成为一位优秀的程序员,要想开发出高质量的软件系统,必须从细处着手,做到内外兼修,本书将为你提供有效的指导。

posted @ 2015-06-13 00:03 奋斗成就男人 阅读(419) | 评论 (0)编辑 收藏

Oracle分析函数入门

一、Oracle分析函数入门

分析函数是什么?
分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值。

          

分析函数和聚合函数的不同之处是什么?
普通的聚合函数用group by分组,每个分组返回一个统计值,而分析函数采用partition by分组,并且每组每行都可以返回一个统计值。

              

分析函数的形式
分析函数带有一个开窗函数over(),包含三个分析子句:分组(partition by), 排序(order by), 窗口(rows) ,他们的使用形式如下:over(partition by xxx order by yyy rows between zzz)。
注:窗口子句在这里我只说rows方式的窗口,range方式和滑动窗口也不提

    

分析函数例子(在scott用户下模拟)

示例目的:显示各部门员工的工资,并附带显示该部分的最高工资。

复制代码
--显示各部门员工的工资,并附带显示该部分的最高工资。
SELECT E.DEPTNO,
E.EMPNO,
E.ENAME,
E.SAL,
LAST_VALUE(E.SAL)
OVER(PARTITION BY E.DEPTNO
ORDER BY E.SAL ROWS
--unbounded preceding and unbouned following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录
--unbounded:不受控制的,无限的
--preceding:在...之前
--following:在...之后
BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
FROM EMP E;
复制代码

运行结果:

               

示例目的:按照deptno分组,然后计算每组值的总和

SELECT EMPNO,
ENAME,
DEPTNO,
SAL,
SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME) max_sal
FROM SCOTT.EMP;

运行结果:

     

示例目的:对各部门进行分组,并附带显示第一行至当前行的汇总

复制代码
SELECT EMPNO,
ENAME,
DEPTNO,
SAL,
--注意ROWS BETWEEN unbounded preceding AND current row 是指第一行至当前行的汇总
SUM(SAL) OVER(PARTITION BY DEPTNO
ORDER BY ENAME
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_sal
FROM SCOTT.EMP;
复制代码

运行结果:

   

示例目标:当前行至最后一行的汇总

复制代码
SELECT EMPNO,
ENAME,
DEPTNO,
SAL,
--注意ROWS BETWEEN current row AND unbounded following 指当前行到最后一行的汇总
SUM(SAL) OVER(PARTITION BY DEPTNO
ORDER BY ENAME
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) max_sal
FROM SCOTT.EMP;
复制代码

运行结果:

   

 示例目标:当前行的上一行(rownum-1)到当前行的汇总

复制代码
SELECT EMPNO,
ENAME,
DEPTNO,
SAL,
--注意ROWS BETWEEN 1 preceding AND current row 是指当前行的上一行(rownum-1)到当前行的汇总
SUM(SAL) OVER(PARTITION BY DEPTNO
ORDER BY ENAME ROWS
BETWEEN 1 PRECEDING AND CURRENT ROW) max_sal
FROM SCOTT.EMP;
复制代码

运行结果:

    

示例目标:   当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总     

复制代码
SELECT EMPNO,
ENAME,
DEPTNO,
SAL,
--注意ROWS BETWEEN 1 preceding AND 1 following 是指当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总
SUM(SAL) OVER(PARTITION BY DEPTNO
ORDER BY ENAME
ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) max_sal
FROM SCOTT.EMP;
复制代码

运行结果:


posted @ 2015-05-13 00:46 奋斗成就男人 阅读(353) | 评论 (0)编辑 收藏

常见分析函数详解

     摘要: 三、常见分析函数详解为了方便进行实践,特将演示表和数据罗列如下:一、创建表create table t( bill_month varchar2(12) , area_code number, net_type varchar(2), local_fare number );      二、插入数据insert i...  阅读全文

posted @ 2015-05-13 00:46 奋斗成就男人 阅读(395) | 评论 (0)编辑 收藏

ORACLE 常用函数

  这个系列我将整理一些日常我们经常使用到的ORACLE函数,鉴于篇幅太长,我大体会按下面分类来整理、汇总这些常用的ORACLE函数,如果有些常用函数没有被整理进来,也希望大家指点一二。

 1: 聚合函数

2: 日期函数
3: 字符串函数
4: 格式化函数
5: 类型转换函数
6: 加密函数
7: 控制流函数
8: 数学函数
9: 系统信息函数
10:分析函数

------------------------------------------聚合函数---------------------------------------------
--1:   AVG(DISTINCT|ALL)

ALL表示对所有的值求平均值,DISTINCT只对不同的值求平均值
SELECT AVG(SAL) FROM SCOTT.EMP;
SELECT AVG(DISTINCT SAL) FROM SCOTT.EMP;
--2:   MAX(DISTINCT|ALL)

求最大值,ALL表示对所有的值求最大值,DISTINCT表示对不同的值求最大值,相同的只取一次

(加不加查询结果一致,不知DISTINCT有什么用途,不同于AVG等聚合函数)
SELECT MAX(DISTINCT SAL) FROM SCOTT.EMP;
SELECT MAX(SAL) FROM SCOTT.EMP
--3:   MIN(DISTINCT|ALL)
求最小值,ALL表示对所有的值求最小值,DISTINCT表示对不同的值求最小值,相同的只取一次
SELECT MIN(SAL) FROM SCOTT.EMP;
SELECT MIN(DISTINCT SAL) FROM SCOTT.EMP;

--4:  STDDEV(distinct|all)
求标准差,ALL表示对所有的值求标准差,DISTINCT表示只对不同的值求标准差
SELECT STDDEV(SAL) FROM SCOTT.EMP;
SELECT STDDEV(DISTINCT SAL) FROM SCOTT.EMP;

--5:   VARIANCE(DISTINCT|ALL)
求协方差  ALL表示对所有的值求协方差,DISTINCT表示只对不同的值求协方差
SELECT VARIANCE(SAL) FROM SCOTT.EMP;
SELECT VARIANCE(DISTINCT SAL) FROM SCOTT.EMP;

--6:  SUM(DISTINCT|ALL)
求和  ALL表示对所有值求和,DISTINCT表示只对不同值求和(相同值只取一次)
SELECT SUM(SAL) FROM SCOTT.EMP;
SELECT SUM(DISTINCT SAL) FROM SCOTT.EMP;


--7:COUNT(DISTINCT|ALL)
求记录、数据个数。 ALL对所有记录,数组做统计, DISTINCT只对不同值统计(相同值只取一次)
SELECT COUNT(SAL) FROM SCOTT.EMP;
SELECT COUNT(DISTINCT SAL) FROM SCOTT.EMP;  
 
----8: MEDIAN
求中位数
SELECT MEDIAN(SAL) FROM SCOTT.EMP;
SELECT MEDIAN(DISTINCT SAL) FROM SCOTT.EMP;  --错误:DISTINCT 选项在此函数中禁用。
----------------------------------------------------------------------------------------------

posted @ 2015-05-13 00:37 奋斗成就男人 阅读(322) | 评论 (0)编辑 收藏

如何判断PHP空间是否支持curl, gzip等功能

在使用PHP时,我们需要将自己写好的php文件上传到已申请的php空间。由于租用或申请的php空间是不允许用户进行配置的,那么对于php的一些功能是否开启,如curl, allow_url_fopen, gzip,就需要提前判断,而不是等写完代码后发现不能使用时,那样改动就大了。

方法/步骤

  1. 其实判断功能是否开启,很简单,我们只需要写一个php文件上传之php空间服务器中。v.php的源代码如图。

    如何判断PHP空间是否支持curl, gzip等功能
  2. 其含义很简单,就是传入一个函数的名字,服务器判断是否存在这个函数,如果存在则表示支持该函数对应的功能,输出“支持”,反之输出“不支持”。将文件上传至php空间中。

    如何判断PHP空间是否支持curl, gzip等功能
  3. 再通过访问空间,地址+v.php?f=+要测试的功能所包括的函数,比如curl功能可以是v.php?f=curl_init,allow_url_fopen功能可以用v.php?f=fopen来测试。

posted @ 2015-04-22 00:04 奋斗成就男人 阅读(295) | 评论 (0)编辑 收藏

从程序员到CTO的Java技术路线图

  在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了。但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平。 

 

Java程序员

高级特性

              反射、泛型、注释符、自动装箱和拆箱、枚举类、可变

              参数、可变返回类型、增强循环、静态导入

        核心编程

             IO、多线程、实体类、

             集合类、正则表达式、

             XML和属性文件

             图形编程

             AWT(Java2D/JavaSound/JMF)、Swing、SWT、JFace

        网路编程

            Applet、Socket/TCP/UDP、NIO、RMI、CORBA

       Java语法基础

           类、抽象类、接口、最终类、静态类、匿名类、内部类、异常类、编码规范

      Java开发环境

          JDK、JVM、Eclipse、Linux

Java核心编程技术

Java,设计而又非常精巧的语言。学习Java,须从Java开发环境开始,到Java语法,再到Java的核心API。

        1.Java开发入门:Java开发环境的安装与使用,包括JDK命令、EclipseIDE、Linux下Java程序的开发和部署等。

        2.Java语法基础:基于JDK和Eclipse环境,进行Java核心功能开发,掌握Java面向对象的语法构成,包括类、抽象类、接口、最终类、静态类、匿名类、内部类、异常的编写。

        3.Java核心API:基于JDK提供的类库,掌握三大核心功能:

        A。Java核心编程:包括Java编程的两大核心功能——Java输入/输出流和多线程,以及常用的辅助类库——实体类、集合类、正则表达式、XML和属性文件。

        B。Java图形编程:包括Sun的GUI库AWT(Java2D、JavaSound、JMF)和Swing,IBM和GUI库SWT和Jface;

        C. Java网路编程:Applet组件编程,Socket编程,NIO非阻塞Socket编程、RMI和CORBA分布式开发。

        4.Java高级特性:掌握JDK1.4、JDK5.0、JDK6.0中的Java高级特性,包括反射、泛型、注释,以及java高级特性——自动装箱和拆箱、枚举类、可变参数、可变返回类型、增强循环、静态导入等。

JavaEE初级软件工程师

JSF框架开发技术

       配置文件(页面导航、后台Bean)、JSF组件库(JSF EL语言、HTML标签、事件处理、)、JSF核心库(格式转换、输入验证、国际化)

Javaweb核心开发技术       

       开发环境(Eclipse、Linux)

       三大组件(JSP、JavaBean、Servlet)

       扩展技术(EL、JSTL、Taglib)

网页开发技术

       HTML、XML、CSS、JavaScript、AJAX

       数据库设计技术

       SQL、MySql、Oracle、SQLServer、JDBC

Web服务器(Tomcat/Jetty/Resin/JBossWeb)

JavaWeb核心技术:

        JavaWeb项目开发的全过程可以分解为:

       网页开发+数据库设计——>JavaWeb项目开发,其中,javaWeb由6项基本技术组成:JSP+JavaBean+Servlet+EL+JSTL+Taglib,而JSF正是将这6种技术进行有机结合的技术框架:

JavaEE中级软件工程师

四种经典架构SSH1、SSI1、SSH2、SSI2

        Struts1表现层框架

      入门配置、核心组件、标签库、国际化、数据检验、数据库开发、Sitemesh集成、集成Hibernate/iBATIS

        Struts2表现层框架

               入门配置、核心组件、标签库、国际化、数据校验、Sitemesh集成转换器、拦截器、集成Hibernate/iBATIS

        Spring业务层框架

              入门配置、IoC容器、MVC、标签库、国际化、数据校验、数据库开发

        Hibernate持久层框架

            MySQL、Oracle、SQLServer iBATIS持久层框架

            MySQL、Oracle、SQLServer

Web服务器(Tomcat/Jetty/Resin/JBossWeb)

Java高级软件工程师

javaWeb开源技术与框架

        工作流、

规则引擎

搜索引擎、

缓存引擎 、

        任务调度、

身份认证

        报表服务、

系统测试、

        集群、

负载平衡、

故障转移

JavaWeb分布式开发技术

JTA(Java事物管理)

      JAAS(Java验证和授权服务)

      JNDI(Java命名和目录服务)

      JavaMail(Java邮件服务)

JMS(java信息服务)

WebService(web服务)

JCA(java连接体系)

JMS(java管理体系)

应用服务器(JBossAS/WebLogic/WebSphere)

JavaEE系统架构师

        面向云架构(COA)

            COA、SaaS、网格计算、集群计算、分布式计算、云计算

        面向资源架构(ROA)

            ROA、RESI

        面向web服务架构(SOA)

           WebService、SOA、SCA、ESB、OSGI、EAI

        Java设计模式

          创建式模式:抽象工厂/建造者/工厂方法/原型/单例

          构造型模式:适配器/桥接/组合/装饰/外观/享元/代理

          行为型模式:责任链/命令/解释器/迭代子/中介者/备忘录/观察者/状态/策略/模板方法/访问者

       Java与UML建模

          对象图、用例图、组件图、部署图、序列图、交互图、活动图、正向工程与逆向工程

CTO首席技术官

         发展战略

         技术总监

         团队提升

         团队建设

         项目管理

         产品管理

企业级项目实战(带源码)地址http://zz563143188.iteye.com/blog/1825168


收集五年的开发资料下载地址:  http://pan.baidu.com/share/home?uk=4076915866&view=share

 

 

 

 

 下面的更深入的有兴趣可以了解一下,我的目的不是要大家掌握下面的知识,只是希望扩展自己的思维,摘自牛人的技术博客。

/**************************************************牛人必看*****************************************************************/

 

 

 

系统后台框架:

 

 

前端工程师技能:

 

 

 

B2C电子商务基础系统架构解析
运营B2C日 久,越来越深刻的意识到IT系统对确保规范化业务流转,支撑消费者端的均一服务有着决定性的作用。于是,一直想好好整理下相关的系统架构,怎奈俗务缠身, 一直拖到今日,猛然发现下周娃很可能就要出生,拖无可拖,快马加笔,居然整出来了。本文的重点是理清系统的逻辑关系,详细的功能模块请参见结尾附上的系统 架构图。
首先,聊下对系统逻辑架构的看法;我个人始终坚持认为,系统的开发与演化,前台严格follow消费者的购买流程,后台则盯牢订单流转,牢牢抓住这两条主线,才能高屋建瓴的看清B2C的逻辑链和数据流,更深刻的规划功能模块,从而更有效支撑实际业务的流转。
前台系统包括:商品展示,内容展示,订单确认,支付系统,用户中心四大模块
一,商品展示
按照Ebay的内部分类,任何将商品以单个或批量的方式展示给消费者的功能均应归入此系统。因此,该系统至少包括:
A,站内搜索(搜索提示,搜索规则,搜索成功页,搜索不成功页,相似推荐)
B,导航(频道导航,其他导航如销售排行,广告位,推荐位,文字链,Also buy等)
C,商品分类(品牌分类,品类分类,属性分类如剪裁形式)
D, 登陆页(商品列表页,商品详细页,商品活动页)
这里的访问逻辑是:A /B/C分流消费者去往相对个性化的页面,由登陆页体现商家的核心诉求和价值传递,完成call-to-action的第一步。
二,内容展示
内容展示较为简单,对纯购物品牌而言包括:
A,公告区
B,帮助中心
C,论坛(如需商城与论坛发生交互,则需自行开发,否则可集成discuz做同步登陆即可)
大家都知道,就不多说了。
三,订单确认
订单确认,就是帮助消费者正确提交订单信息的环节,看似简单,实则非常复杂,需要对很多信息逻辑判断和处理,一般由2个部分组成:
A,购物车(购物车浮层,购物车页面,无注册购买)
无注册购买是需要慎用的功能,除非刻意追求用户的短平快下单,如团购/换购,一般不推荐使用,会造成系统异常复杂,开发量也很大。
B,订单提交(返回购物车,收货地址&地址薄,支付方式判断,配送方式,发票,订单标记,实付金额计算等等)
值得一提的是,几乎大多数的促销逻辑运算在这个环节完成,充分考虑各种促销方式之间的互斥与重叠是系统设计的核心,需要充分考虑各种情况,避免出现逻辑漏洞。
四,支付系统
与一般的想象不同,支付系统其实并不简单等于第三方支付工具接入:
A,外部支付系统(支付宝将接口,财付通接口,网银直联端口,信用ka分期端口)
B,内部支付系统(账户余额,积分,礼品卡,优惠券)
支付系统的逻辑设计不但需要考虑到各种极端情况的发生(如一张订单先用礼品卡,再用积分,最后网银支付),还要预留财务做账所需的相关字段,并充分考虑订单取消之后如何回滚各类内部账户。
五,用户中心
用户中心的实质是用户自助功能的dashboard,一般4个部分组成:
A,注册&登陆(快速注册,完整注册,注册有礼,推荐注册,密码找回,主站id登陆,open-id登陆如QQ,新浪微博等)
B,订单中心(历史订单状态,中间状态订单修改,物流追踪)
C,服务中心(各类自助服务如退款申请,退换货申请,建议与投诉等)
D, 信息管理(用户基本信息管理和账户信息管理)
用户中心的价值在于:尽可能引导用户自行获取所需的信息并提交所需的服务,在提升服务准确率,及时性的同时降低对人工成本。
后台系统包括:商品&促销,CRM,订单处理,WMS,采购管理,财务管理,报表管理,系统设置,WA系统9大模块
一, 商品&促销
商品&促销模块的核心在于确保消费者下单之前,前台内容所见即所得
A, 商品管理(品类管理,品牌管理,单品管理)
B, 促销管理(活动管理和自定义活动模板管理)
在上述模块中,最重要的是2个部分:单品管理中的批量产品生成的自动程序和活动管理中“共享与互斥”管理。前者用于大幅提升上新速度,后者避免促销活动失控。
二, CRM
CRM是对B2C核心资源—会员的管理,服务与再营销系统,包括如下部分:
A,会员管理(会员信息的增删改查和到其他系统的链接)
B,用户关怀(条件触发和人工触发相关EDM & 短信 & OB)
C,定向营销(会员分组和营销活动管理)
D, 客服管理(内容非常多,集成所有需前台与后台交互的功能,详情还是看图吧)
E, 呼叫中心(IVR,坐席管理,统计报表,参数传递与窗口嵌入)
值得注意的,EDM和短信通道市面上已经有成熟的外包服务商,一般都会外包;呼叫中心和在线客服自行开发成本太高,特别是呼叫中心系统,业务初期也都是外包的。
三, 订单处理
订单处理是在订单未正式进入仓储部门处理之前,对订单的前置性处理环节。
A,订单录入(电话订购,网上下单,外部团购订单,无金额订单录入如礼品单)
B,订单审核(自动审核和人工审核)
C,RMA处理(RMA申请单和RMA处理单)
RMA的逻辑也异常复杂,需要在效率和成本之间找平衡,确保在不拖垮仓储部门的正常出入库的前提下对消费者端快速有效close工单;对内部则需要控制成本,货损不能超过预算上限。
四, WMS(Warehouse Management system仓库管理系统)
WMS的流程很长,功能模块也很多,大致分为入库管理,库存管理,出库管理和票据管理4个模块四个模块,细细道来就是另外一篇文章了,各位可以参考 我这篇文章:庖丁解牛—B2C仓储内部运作解密(上,中,下)http://blog.sina.com.cn/wangxida0855
五, 采购管理
采购管理的核心是有效跟进采购合同/发票的状态,大货的采购入库/退库,财务结算和在仓库存查询和处理。
A,供应商管理(供应商信息管理,合同发票管理)
B,采购单管理(PO单管理,负PO单管理)
C,库存管理(库存查询,库存占用单,库存变动log)
六, 财务管理
B2C的财务管理,主要是对供应商,渠道和内部费用支出的成本控制。
A,供应商结算
B,渠道结算
C,配送结算
D, 内部结算
说实在的,哥对财务这块也不算很了解,大家将就看看,图片上有明细。
七, 报表管理
报表是B2C业务的宏观表现,理论上说,每个部门的KPI都应该从中找到。
A,搜索报表(站内搜索量查询)
B,销售报表(多个维度销量查询,优惠券使用情况,报表导出)
C,财务报表
D, 客服报表(客服日报和坐席报表)
前者反映与消费者发生的日常交互(包括正常与异常),后者考核客服的工作绩效
E, 仓储物流报表
这几块报表,是业务运作的核心,涉及到公司机密,就不能写的太细了,见谅。
八, 系统设置
这块大家都知道是干嘛的,也就不多说了,分成三块。
A,基础设置(和业务有关的一些字段值)
B,权限设置(不同账号的操作权限和操作记录)
C,其他设置
九, WA系统(Web Analytcis)
网站分析系 统,几乎全是外购,很少有能够自建的,即使自建,最多做几个简单的模块。用于实战的,要么是免费的GA(Google Analytics),要么是昂贵的Omniture。这块的知识,细细说来也是另外一篇文章了,有兴趣的同学可以看我这篇科普文章:揭秘—我所知道的网 站分析(上,下) http://blog.sina.com.cn/wangxida0855
最后,上全系统大图,再感慨一句,B2C系统,真是一个大工程啊。

 

fr  http://blog.sina.com.cn/s/blog_59d6717c0100syh3.html

posted @ 2015-04-11 13:41 奋斗成就男人 阅读(236) | 评论 (0)编辑 收藏

ajax+json+Struts2实现list传递(转载)

     摘要: ajax+json+Struts2实现list传递(转载)一、首先需要下载JSON依赖的jar包。它主要是依赖如下:      json-lib-2.2.2-jdk15      ezmorph-1.0.4       commons-logging-1.0.4&nbs...  阅读全文

posted @ 2015-04-04 01:17 奋斗成就男人 阅读(346) | 评论 (0)编辑 收藏

iBatis简单入门教程

     摘要: Batis 简介:iBatis 是apache 的一个开源项目,一个O/R Mapping 解决方案,iBatis 最大的特点就是小巧,上手很快。如果不需要太多复杂的功能,iBatis 是能够满足你的要求又足够灵活的最简单的解决方案,现在的iBatis 已经改名为Mybatis 了。官网为:http://www.myb...  阅读全文

posted @ 2015-04-04 01:16 奋斗成就男人 阅读(193) | 评论 (0)编辑 收藏

PHP页面跳转代码

第一篇: JavaScript 跳转

方法一:

<script language="javascript">
    window.location= "http://www.baidu.com";
</script>

方法二:

<script language="javascript">
    document.location = "http://www.baidu.com";
</script>

方法三: (带进度条)

<html>
<head>
<meta http-equiv="Content-Language" content="zh-cn">
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
<title>跳转到baidu.com</title>
</head>
<body>
<form name=loading>
<P align=center><FONT face=Arial color=#0066ff size=2>loading...</FONT>
<INPUT style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bolder; PADDING-BOTTOM: 0px; COLOR: #0066ff; BORDER-TOP-style: none; PADDING-TOP: 0px; BORDER-RIGHT-style: none; BORDER-LEFT-style: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-style: none"
size=46 name=chart>
<BR>
<INPUT style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; COLOR: #0066ff; BORDER-BOTTOM: medium none;" size=47 name=percent>
<script language="javascript">
var bar=0
var line="||"
var amount="||"
count()
function count(){
    bar=bar+2
    amount =amount + line
    document.loading.chart.value=amount
    document.loading.percent.value=bar+"%"
    if (bar<99){
        setTimeout("count()",100);
    }else{
        window.location = "http://www.baidu.com/";
    }
}
</script>
</P>
</form>
</body>
</html>

第二篇: 页面跳转

<head>
<meta http-equiv="refresh" content="10; url=http://www.baidu.com">
</head>

第三篇: 动态页面跳转

方法一: PHP 跳转

<?php
header("location: http://www.baidu.com");
?>


方法二: ASP 跳转

<%
response.redirect "http://www.baidu.com"
%>

FYI:
<%
Dim ID1
Dim ID2
dim str
ID1 = Request("forumID")
ID2 = Request("threadID")
str="/blog/threadview.asp?forumID="& ID1 &"&threadID=" & ID2
response.redirect str
%>
<%
response.redirect "http://www.baidu.com"
%>

FYI:
<%
Dim ID1
Dim ID2
dim str
ID1 = Request("forumID")
ID2 = Request("threadID")
str="/blog/threadview.asp?forumID="& ID1 &"&threadID=" & ID2
response.redirect str
%>

posted @ 2015-04-01 17:08 奋斗成就男人 阅读(234) | 评论 (0)编辑 收藏

zencart使用smtp发邮件设置

zencart如何设置smtp发邮件,zencart不能发email,发email失败怎么办?zen cart要使用gmail发送邮件,首先要把你的gmail账户开通pop/smtp, 然后再zencart后台设置邮件发送方式,邮箱帐号,密码。 
具体操作方法如: 
进入后台--商店设置--电子邮件,首先选择”电子邮件发送方式“为smtpauth。然后输入你的gamil邮箱地址。 
最后设置

1)首先后台电子邮件 发送方式是:smtpauth
2)smtp帐号邮箱:xxx@gmail.com
3)smtp帐号密码:xxxxxxxx
4)smtp主机:smtp.gmail.com
5)smtp服务器端口:465或者587

注意:国内的邮箱最好使用163邮箱:服务器:smtp.163.com  端口:465/25,其他的邮箱不能发,具体原因暂时不清楚。

如果这样设置是正确的。但是有些主机还是会出现Email Error: SMTP Error: Could not connect to SMTP host.这样的情况 。

这个需要服务器支持。检查下后台-工具-服务器信息里是否有OpenSSL。因为google 传输是ssl://smtp.gmail.com协议。

所以需要服务器支持Openssl这个尤为重要。

补充重要情况:电子邮件必须从现有域名发送  设置成 no


zencart-email-smtp.png
zencart-email-smtp.png

 

如果还是发不了email,可参考下面的技术细节:

在服务器上 telnet smtp.gmail.com 465 确定能连接

yum -y install openssl 安装ssl,重启apache在试一试

 

 

 开通gmail帐号的pop/smtp功能:
gmail-pop-smtp.png

 

Zen Cart后台邮件发送不成功的解决办法,错误提示“电子邮件错误: The following From address failed: ”
几个需要注意的设置项:
1、服务器应启用SMTPAUTH电子邮件发送方式;
2、检查SMTP帐号、邮箱、密码、邮件服务器域名和端口是否设置正确。
3、发件人邮件地址要用你的SMTP邮箱帐号,并且电子邮件必须从现有域名发送设为Yes.

* 如果上述都没错,请多换其他SMTP账户/邮箱测试。推荐gmail

收费调试服务

我们希望您能自己搞定这些问题,但是如果你多方测试都无法找到发邮件不成功的解决办法,我们也提供收费调试服务。诊断调试要花费技术很多时间,调试一次需要的时间可能很长,估计2-5小时。每次调试收费200元。保证帮你调试到前台 联系我们 contact us 页面能发送邮件

posted @ 2015-04-01 14:47 奋斗成就男人 阅读(1367) | 评论 (0)编辑 收藏

linux下导入、导出mysql数据库命令

一、导出数据库用mysqldump命令(注意mysql的安装路径,即此命令的路径):
1、导出数据和表结构:
mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql
#/usr/local/mysql/bin/   mysqldump -uroot -p abc > abc.sql
敲回车后会提示输入密码

2、只导出表结构
mysqldump -u用户名 -p密码 -d 数据库名 > 数据库名.sql
#/usr/local/mysql/bin/   mysqldump -uroot -p -d abc > abc.sql

注:/usr/local/mysql/bin/  --->  mysql的data目录


二、导入数据库
1、首先建空数据库
mysql>create database abc;

2、导入数据库
方法一:
(1)选择数据库
mysql>use abc;
(2)设置数据库编码
mysql>set names utf8;
(3)导入数据(注意sql文件的路径)
mysql>source /home/abc/abc.sql;
方法二:
mysql -u用户名 -p密码 数据库名 < 数据库名.sql
#mysql -uabc_f -p abc < abc.sql

建议使用第二种方法导入。

注意:有命令行模式,有sql命令

posted @ 2015-03-26 14:19 奋斗成就男人 阅读(202) | 评论 (0)编辑 收藏

那些强悍的PHP一句话后门[转]

     摘要: 我们以一个学习的心态来对待这些PHP后门程序,很多PHP后门代码让我们看到程序员们是多么的用心良苦。强悍的PHP一句话后门这类后门让网站、服务器管理员很是头疼,经常要换着方法进行各种检测,而很多新出现的编写技术,用普通的检测方法是没法发现并处理的。今天我们细数一些有意思的PHP一句话木马。利用404页面隐藏PHP小马:01<!DOCTYPE HTML PUBLIC  "-...  阅读全文

posted @ 2015-02-25 14:18 奋斗成就男人 阅读(2488) | 评论 (0)编辑 收藏

如何创建magento模块之Hello World例子

步骤:
1.创建一个Hello World模块
2.为这个模块配置路由
3.为这个模块创建执行控制器

 

创建Hello World模块



创建模块的结构目录:
app/core/local/Sjolzy/HelloWorld/Block
app/core/local/Sjolzy/HelloWorld/controllers
app/core/local/Sjolzy/HelloWorld/etc
app/core/local/Sjolzy/HelloWorld/Helper
app/core/local/Sjolzy/HelloWorld/Model
app/core/local/Sjolzy/HelloWorld/sql
创建config.xml的内容(app/core/local/Sjolzy/HelloWorld/etc/config.xml):
<config>
 <modules>
  <Sjolzy_HelloWorld>
   <version>0.1.0</version>
  </Sjolzy_HelloWorld>
 </modules>
</config>
然后创建一个系统配置文件激活这个模块
Sjolzy_HelloWorld.xml(app/etc/modules/Sjolzy_HelloWorld.xml)
<config>
 <modules>
  <Sjolzy_HelloWorld>
   <active>true</active>
   <codePool>local</codePool>
  </Sjolzy_HelloWorld>
 </modules>
</config>
检查是否模块已经激活:先清空magento缓存(var/cache),在后台管理:System->Configuration->Advanced 展开Disable Modules Output,看是否Sjolzy_HelloWorld显示出来。
 

配置路由


路由是用来把一个URL请求转换成一个执行控制器的方法。
需要在magento的全局配置中显式的定义你的路由。
在config.xml(app/core/local/Sjolzy/HelloWorld/etc/config.xml)中:
<config>
 ...
 <!-- /*  fontend:指向网站的前台(也可以是admin|install) */ -->
 <frontend>
  <!-- /*  routers:路由对象的定义或路由路径的定义 */ -->
  <routers>
   <!-- /*  helloworld:指向网站的前台 */ -->
   <helloworld>
    <use>standard</use>
     <args>
      <!-- /*  module:模块名字的小写版本 */ -->
      <module>Sjolzy_HelloWorld</module>
      <!-- /*  fontName:路由过程中的一个参数,只跟路由相关(Front Controller则是用来实例化所有路由) */ -->
      <frontName>helloworld</frontName>
     </args>
   </helloworld>
  </routers>
 </frontend>
</config>
 

为路由创建执行控制器


路由会把控制权交给控制器,我们已经定义了路由,现在来定义我们的执行控制器。
app/code/local/Sjolzy/HelloWorld/controllers/IndexAction.php(模块的控制器放在子目录controllers<小写>里,这是magento的规定)
<?php
class Sjolzy_HelloWorld_IndexController extends Mage_Core_Controller_Front_Action{
 public function indexAction(){
  echo 'Hello World!';
 }
}
?>

还是情况缓存,请求URL:http://example.com/helloworld/index/index
注:http://example.com/frontName/执行控制器/执行方法


如果看到空白页面上写着'Hello World!',则你的模块创建成功!

posted @ 2015-02-25 12:06 奋斗成就男人 阅读(208) | 评论 (0)编辑 收藏

如何在magento中建立自定义页面

老话重提,我们还是通过URL来进行分析

http://<host>/<Magento虚拟目录>/<config.xm中的frontName>/<Controller文件名去掉Controller>/<Controller文件的方法名去掉Action>

例如,我们现在想在paypal的模块中,增加一个查看帮助的页面。

访问url为:
http://youip/paypal/standard/help

那么我们反向分析。根据之前的分析,我们找到控制文件
\app\code\core\Mage\Paypal\controllers\StandardController.php
在里面增加一个方法
  1. public function helpAction()
  2.        {
  3.   
  4.    $this->loadLayout();
  5.          $this->_initLayoutMessages('paypal/session');
  6.          $this->renderLayout();
  7.        }
其中:$this->loadLayout();将载入\app\design\frontend\default\default\layout\目录下的paypal.xml
增加以下片段:
  1.     <paypal_standard_help>
  2.       <!-- Mage_Paypal -->
  3.          <remove name="right"/>
  4.          <remove name="left"/>

  5.       <reference name="root">
  6.       <action method="setTemplate">
  7.          <template>/page/1column.phtml</template>
  8.           </action>
  9.       </reference>
  10.       <reference name="content">
  11.       <block type="paypal/standard_help" name="paypal_standard_help" template="paypal/standard/help.phtml"/>
  12.       </reference>
  13.    </paypal_standard_help>  
接着建立block类文件,\app\code\core\Mage\Paypal\Block\Standard\Help.php
  1. class Mage_Paypal_Block_Standard_Help extends Mage_Directory_Block_Data
  2. {
  3.    public function getHelp(){
  4.          return "this is paypal help file content!";
  5.        }
  6. }
最后建立模板文件
\app\design\frontend\default\default\template\paypal\standard\help.phtml
  1. <?php echo $this->getHelp(); ?> 

posted @ 2015-02-25 12:06 奋斗成就男人 阅读(619) | 评论 (1)编辑 收藏

服务端XMLHTTP(ServerXMLHTTP in ASP)应用

近几年很流行 Ajax,而 Ajax 的本质就 是 XMLHttpRequest,是客户端 XMLHttpRequest 对象的使用。相对于 Ajax,服务端 XMLHTTP 就是在服务端使 用 XMLHttpRequest 对象了。虽然说,在服务端使用异步请求是比较不方便的,但是做为可以服务端发送 HTTP 请求的组件,学习一下也是 没有坏处的。[喝小酒的网摘]http://blog.const.net.cn/a/2589.htm

这里,我讲的是在 ASP 环境中使用服务端 XMLHttpRequest,并以 JScript 做为演示代码的语言,因此,你需要了解 ASP 以及 JScript。

服 务端 XMLHTTP,通常会用在获取远程主机的网页或者其他内容,新闻聚合系统一般就是使用服务端 XMLHTTP 对象来获取要聚合的 Feed 的 内容,然后使用 XMLDOM 对象来分析 Feed 的内容,取出新闻的标题、作者、内容等信息,再存在数据库中,然后将若干个数据源的新闻一起显示在 一起。抓虾就是这样一个新闻聚合器,但是它不是用 ASP 写的就是了 :)

在 ASP 中,我们可以用以下代码来创建一个 ServerXMLHTTP 对象,而这个对象,就是我们在服务端进行一切操作的基础。
程序代码:

// demo code from xujiwei
// @website: http://www.xujiwei.cn/
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");

首先来了解一下 ServerXMLHTTP 对象有哪些比较有用的方法:

1. abort 这个方法用于取消 XMLHTTP 的请求。如果 XMLHTTP 对象以异步方式发送请求,如果到达一定的时间请求仍然没有返回,就可以使用这个方法来取消请求。

2. getAllResponseHeaders 这个方法的返回值是一个字符串,相当于 HTTP 请求的头部去掉了请求方法、URI和协议版本信息。

3. getResponseHeader 这个方法用来获取指定头部信息,比较有用的就是可以用来获取返回数据的 Content-Type、Referer 等。

4. open 使用指定的请求方法、URI和同步方式以及认证信息等初始化一个请求。

5. send 发 送 HTTP 请求,等待接收响应数据,注意,如果是以同步方式发送请求,send方法调用后不会立即返回,而是等到请求完成后才会返回,而以异步方法请 求时,则会立即返回。另外,send方法带有一个可选参数body,表示要发送的数据,这在使用 POST 方法时比较有用。

6. setTimeout 设置 ServerXMLHTTP 对象的 4 个超时时间,分别是:域名解析、连接服务器、发送数据、接收响应。可以通过设置相应的超时时间来控制 ServerXMLHTTP 对象,以免 ServerXMLHTTP 不能及时返回而造成程序停止响应。

7. setRequestHeader 设 置请求的 Header,在客户端 XMLHttpRequest中,通常用来设置请求的数据类型,或者标识请求的方法等等,例如 jquery 会增加 头部标识 X-Request-With,表示请求是从 XMLHttpRequest 对象发出,以方便服务端做出相应的动作。

8. waitForResponse 在使用异步方式发送请求时,可以用这个方法来控制请求的进程。在服务端脚本中,不可以像客户端那样直接使用回调函数来控制异步请求,也没有相应的函数来使用程序休眠一定的时间,因此,为了等待请求返回,我们可以使用这个方法来等待一定时间。

另外,还有其他一些方法,如 getOption、setOption、setProxy 等,这些方法用得比较少,因此这里不再介绍,需要了解的朋友可以查阅 MSDN。

接下来,再看看 ServerXMLHTTP 对象的属性:

1. onreadystatechange XMLHTTP 对象状态改变时的回调函数,这个属性为异步操作奠定了一个基础,可以让程序在不用查询 XMLHTTP 对象状态的情况获知 XMLHTTP 操作是否已经完成。

2. readyState XMLHTTP 对象状态,有 5 个值,从 0 到 4,分别代表的意思是:

0 - 未初始化,刚使用 new ActiveXObject("MSXML.ServerXMLHTTP.5.0") 创建时对象所处的状态

1 - 载入中,这个时候,已经调用了 open 方法,但是还没有使用 send 方法发送数据

2 - 已经载入,已经调用了 send 方法发送数据,但是还没有可用的响应流

3 - 正在交互,正在接收数据,这个时候可以使用 responseBody 和 responseText 属性来获取已经得到的部分数据了

4 - 完成请求,全部数据已经接收完成

通常情况下,我们只需要判断一下状态 4 即可,这个时候数据已经全部载入,使用 responseBody 或 responseText 属性就能获取需要的数据。

3. status HTTP 响应状态码,正常情况应该为 200,如果请求的资源不存在,就会返回 404,还有其他状态码如服务器错误 500 等。

4. statusText HTTP 响应状态文本,用于描述响应状态码所代表的意思,诸如 200 OK 中的 OK,404 Not Found 中的 Not Found

5. responseBody 响应数据的字节数组,这在 VBScript 里是可以直接使用的,但是在 JScript 里就需要转换过了。

6. responseText 以文本方式获取响应数据

7. responseXML 将响应数据作为一个 XMLDOM 对象来返回,这在请求的数据是一个 XML 文档时特别有用

8. responseStream 响应流对象,这个属性不常用
在 ServerXMLHTTP中,异步请求不再是主要用途,往往是同步的请求用得更多,因为在服务端编程中,程序的执行是需要迅速结束并返回结果的,不像在 桌面程序中,有一个消息循环。这样就导致了在服务端编程中,同步编程用得更多。当然,这并不是说异步请求没有用处,在一定的情况下,异步请求会有很大的作 用。

1. 简单的使用ServerXMLHTTP请求并显示指定Url

首先来看一下很简单的例子,使用ServerXMLHTTP请求Google的首页并显示出来:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
var url = "http://www.google.cn";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
xmlhttp.open("GET", url, false);
xmlhttp.send("");
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>

在浏览器查看这个页面,你就可以看到Google的首页了:

图片附件

但是,我们可以看到,这里的Logo图片是没有显示的,因为这个logo在网页源代码里是以相对路径的方式来指定的:

<img src=/intl/zh-CN/images/logo_cn.gif width=286 height=110 border=0 alt="Google" title="Google">

但是,我们的测试服务器里并没有这个图片文件,因此浏览器就会显示此图片的替代文字“Google”。

这 里我使用了xmlhttp的responseBody属性,这是因为,在不知道所请求的网页是使用什么编码的情况下,可以让浏览器来处理这个问题,而不用 在服务器处理编码。如果要在服务器处理编码,你必需知道你所请求的URL所返回的内容是使用什么编码的,并且正确的将返回内容进行转码以使得客户端浏览器 能正常的显示。

例如,我们请求Baidu的首页,就会因为编码问题而导致页面完全错乱:

图片附件

所以,使用responseText或者responseBody,完全取决于我们的需要,并不是一成不变的,或者,在某些时候,我们要使用的并不是这两个中的一个,而是responseXML:)

2. 设置超时

在 使用ServerXMLHTTP发送同步请求时,整个ASP程序的执行是被阻塞了的,也就意味着在开始发送请求到请求完成响应这段时间里,我们是做不了任 何事情的。那么这里就有几个问题,如果所请求的域名解析很慢怎么办?如果程序运行的服务器与请求的服务器之间的网络环境比较差导致连接很慢怎么办?如果要 发送的数据量很大但是带宽不够怎么办?同样如果响应的数据量很大但是带宽不够怎么办?

服务器所在环境及网络条件我们是无法改善的,因为,面对这些问题,我们只能采取回避的策略,即如果碰到这些问题,我们就直接丢掉这个请求。这时,ServerXMLHTTP的超时机制就有很大的用处了。

在 前一篇中,我介绍了ServerXMLHTTP的常用方法,其中有一个setTimeouts方法,就是用来设置ServerXMLHTTP对象的四个超 时时间,分别是:域名解析超时时间(resolveTimeout)、连接超时时间(connectTimeout)、数据发送超时时间 (sendTimeout)、数据接收超时时间(receiveTimeout)。这四个超时时间所代表的意义可以从它们的字面来理解,它们分别对应了这 一节开头所提出一的四个问题。

在不使用setTimeouts方法进行设置的情况下,域名解析超时时间(resolveTimeout)是 无限的,即不会在域名解析时产生超时,连接超时时间(connectTimeout)的默认值为60秒,数据发送超时时间(sendTimeout)的默 认值为30秒,数据接收超时时间(receiveTimeout)的默认值也是30秒。

通常情况下,我们不需要默认值中所指定的那么长的超时时间,因为碰到了最坏的情况下,在一个页面显示时,访客将要面对2分钟左右的无响应时间,这时访客往往认为这个页面是无效的并且会离开这个页面。

所 以我们要做的就是给ServerXMLHTTP设置一个较短的超时时间,一般情况下,域名解析和连接远程服务器都可以在2秒内完成,发送数据时间视数据量 而定,如果只是使用GET请求,这个数据量是很小的,也可以在2秒内完成,而响应,则可以稍微长一点,定在10秒左右,超过10秒时可以认为远程服务器没 有响应。

需要注意的是,setTimeouts方法所使用的参数单位是以毫秒为单位的,也就是说,如果 要指定2秒的超时时间,所用的参数为2000。另外,setTimeouts的参数顺序也是固定的,按顺序为:域名解析超时时间 (resolveTimeout)、连接超时时间(connectTimeout)、数据发送超时时间(sendTimeout)、数据接收超时时间 (receiveTimeout)。

那么,可以使用下面的代码来完成超时设置:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
var url = "http://www.google.com";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
// 设置超时时间,注意参数顺序
xmlhttp.setTimeouts(2000, 2000, 2000, 10000);
xmlhttp.open("GET", url, false);
xmlhttp.send("");
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>

如 果在某个阶段超时了,程序会抛出异常,在JScript里可以使用try...catch来捕获,并根据ServerXMLHTTP对象的 readyState属性来获知是在哪个阶段产生了超时异常。注意,同步请求时,超时异常会发生在调用send方法所在的行,例如上例中的 xmlhttp.send("")。
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
var url = "http://www.youtube.com/";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
// 设置超时时间,注意参数顺序
xmlhttp.setTimeouts(2000, 2000, 2000, 10000);
xmlhttp.open("GET", url, false);
try {
xmlhttp.send("");
}
catch(e) {
Response.Write("发生异常:" + e.message + "<br/>");
// 判断是否为超时错误
if(e.number == -2147012894) {
var step = "";
// 判断超时错误发生所在的阶段
switch(xmlhttp.readyState) {
case 1:
step = "解析域名或连接远程服务器"
break;
case 2:
step = "发送请求";
break;
case 3:
step = "接收数据";
break;
default:
step = "未知阶段";
}
Response.Write("在 " + step + " 时发生超时错误");
}
Response.End();
}
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>
3. 请求使用HTTP认证的页面

呃,虽然说目前使用HTTP基本认证的已经少之又少,但是,总该知道ServerXMLHTTP有这么一个功能,可以直接实现HTTP基本认证。

在ServerXMLHTTP对象的open中,我们通常用到的只是它的前3个参数,即method、uri、async,但事实上,它还有另外两个可选参数,即用于HTTP基本认证的username及password。

那么,如果某天,我们要使用ServerXMLHTTP访问某个使用HTTP基本认证的网站,并且我们已经有了认证所需要的用户名及密码,那么可以使用以下密码来访问需要认证的内容:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
// 访问www.google.cn并不需要HTTP认证,这里只是作为一个演示
var url = "http://www.google.cn";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
// 用户名和密码分别为username和password
xmlhttp.open("GET", url, false, "username", "password");
xmlhttp.send("");
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>

4. 使用responseXML属性

有时候,我们所需要的结果并不是文本的,而是一个XML文档,譬如目前最常用的RSS。这个时候,responseXML属性就是我们的不二选择了。

使用responseXML属性所得到的对象,就是一个DOMDocument对象,这个对象可以使用诸如selectNodes、selectSingleNode这样的方法来操作XML文档对象。

例如,我们可以利用ServerXMLHTTP抓取新浪新闻的RSS并显示出来:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
// 新浪新闻的RSS地址
var url = "http://rss.sina.com.cn/news/marquee/ddt.xml";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
xmlhttp.open("GET", url, false);
xmlhttp.send("");
var xml = xmlhttp.responseXML;
Response.Write("<h1>" + xml.selectSingleNode("/rss/channel/title").text + "</h1>");
var items = xml.selectNodes("/rss/channel/item");
for(var i = 0; i < items.length; i++) {
Response.Write("<h3>" + items[i].selectSingleNode("title").text + "</h3>");
Response.Write("<small>" + items[i].selectSingleNode("pubDate").text + "</small>");
Response.Write("<div>" + items[i].selectSingleNode("description").text + "</div><hr />");
}
items = null;
xmlhttp = null;
%>

这些如果弄明白了,写一个RSS新闻聚合器就不是难事了。当然XMLDOM操作就不在本系列的范围之类了。
服务端XMLHTTP(ServerXMLHTTP in ASP)进阶应用-User Agent伪装

这篇开始讲讲ServerXMLHTTP的进阶应用。说是进阶应用,但也就是讲一些在基本应用里没有讲到的属性或者方法之类:)

使用setRequestHeader伪装User-Agent

User-Agent一般是服务端程序用来判断客户端浏览器、操作系统等信息的标志,它的说明可以参考Wiki,譬如在我的电脑 IE7 的UA就是:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ;

SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618)

可以看到,这个UA提供了不少信息,IE版本、Windows版本、.NET版本都有。再看看 Firefox 的:

Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3 (.NET CLR 3.5.30729)

UA的格式不是本文的重点,因此,如果需要了解UA的具体格式,可以去Google上找找,另外,在http://www.user-agents.org/这里可以找到目前大多数浏览器、搜索引擎Spider等的UA。

在我们使用 ServerXMLHTTP 发送请求时,它所用的 User-Agent 是以下内容:

Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)

但是,某些网站会限制这个UA的访问,比如Google,如果我们使用以下代码来请求Google的页面,它使用的是默认UA“Mozilla/4.0 (compatible; Win32; WinHttp.WinHttpRequest.5)”:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
var url = "http://news.google.cn/?output=rss";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
xmlhttp.open("GET", url, false);
//xmlhttp.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3 (.NET CLR 3.5.30729)");
xmlhttp.send("");
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>

你会发现,我们会收到一个 403 Forbidden 的错误:

图片附件

为 了使得Google的RSS输出程序能把我们的识别成正常的RSS阅读或者一般浏览器,就需要在请求发出前设置 Request Header。要设 置 Request Header,只需要简单的在调用 open 方法之后,send 方法之前使用 setRequestHeader 来设置就行 了,它的语法是 xmlhttp.setRequestHeader(key, value)。下面我们就让Google的RSS输出程序把我们的请求识 别为Firefox的请求:
程序代码:

<%@LANGUAGE="JScript" CODEPAGE="65001"%>
<%
// code from xujiwei
// http://www.xujiwei.cn
var url = "http://news.google.cn/?output=rss";
var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.5.0");
xmlhttp.open("GET", url, false);
// 设置 User Agent 为 Firefox 的UA
xmlhttp.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3 (.NET CLR 3.5.30729)");
xmlhttp.send("");
Response.BinaryWrite(xmlhttp.responseBody);
xmlhttp = null;
%>

刷新浏览器,显示出了Firefox的RSS预览界面,获取Google资讯RSS成功!

图片附件

ok,我们能正确得到Google资讯的RSS了,再通过XMLDOM来操作返回的RSS文档,就可以采集Google资讯那海量的新闻了。
[喝小酒的网摘]http://blog.const.net.cn/a/2589.htm

转载自 [blog.const.net.cn]喝小酒的网摘 及本文链接地址:http://blog.const.net.cn/a/2589.htm

相关文章
  • 发生msxml3.dll,错误800c0005错误的原因和解决方法
  • Function getHTTPPage(url)
    dim http
    set http=Server.createobject("Microsoft.XMLHTTP")
    Http.open "GET",url,false
    Http.send()
    if Http.readystate<
  • 定时运行ASP文件
  • 在一定的时候,要定时的运行某个ASP文件去执行一个任务,如一个工厂在早上9点钟要采集所有的电表的读数,当然这要通过IN SQL连接到各个电表中,我们现在就是用一个ASP文件把IN SQL中表的读数再集中到MS SQL中。

    可能你看到的定时运行ASP文件的方法有多种,不过我现在要说的是一种简单的方法,利用计划任务就可简单的实现。

    首先,你要
  • 安装asppdf的几种方式
  • asppdf其实只有一个文件,也就是asppdf.dll,安装的时候只需要复制到系统system32目录下,然后regsvr32就可以了,当然你 也可以去官方网站下载asppdf.exe,安装程序不会把asppdf.dll复制到system32,但他还是已经regsvr32了,并且有一些示 例代码,也自动新建了一个虚拟目录/asppdf。也就是说可以直接http://localhost/asppd
  • xmlhttp属性和方法
  • 下面是WinHttpRequest component,不过我想也应该适用于xmlhttp,
    前文有讲到xmlhttp的属性与方法,但觉得不是很完整,所以就有了下面的补充,下面的这些数据是来自于Microsoft,估计这个是比较全的,但里面提到的一些方法,例如属性(property-get)Option,在xmlhttp中平时都没有用过,又比如function SetTimeouts
  • asp中使用xmlhttp下载图片代码
  • asp中使用xmlhttp下载图片代码:
    <%
    function getHTTPimg(url)
    dim http
    set http=server.createobject("MSXML2.XMLHTTP")
    Http.open "GET",url,false
    Http

    posted @ 2015-02-05 00:45 奋斗成就男人 阅读(583) | 评论 (0)编辑 收藏

    国内PHP开源建站程序一览

    国外的开源技术也影响和推动了国内开源程序的发展,上文我介绍的《国外优秀开源PHP建站程序一览》中,很多国外开源程序并不太符合中国人的使用习惯,而国内有一些厂家或个人也做了一些不错的产品,不少程序是提供源代码下载的,虽然有些在许可协议上和开源许可证有些出入,但其在使用上还是挺符合中国人的使用习惯,今天我就介绍一些国内的PHP“开源”建站程序。

      论坛:Discuz

      Discuz非常流行,也是中国地区最多用户使用的论坛程序,论坛搭建非常简单易用,使用风格符合中国人的口味。另一个流行的论坛程序是PHPWind

      SNS:Ucenter Home

      UCenter Home是采用PHP+MySQL构建的社会化网络软件(Social Network Software,简称SNS)。 通过 UCenter Home,建站者可以轻松构建一个以好友关系为核心的交流网络,用户可以使用迷你博客记录;方便快捷地发布日志、上传图片;与其好友们一起分享信息、讨论话题;了解好友最新动态。

      E-Commerce:ECSHOP

      ECSHOP是一款开源免费的网上商店系统,用户可以根据自己的商务特征对ECSHOP进行定制,增加自己商城的特色功能。另一个流行的网上商城系统是shopex

      点评:Modoer

      Modoer一款PHP点评系统,可针对多种行业进行点评,可以自由调控点评项目,类型,采用Web 2.0的建站方式,网站会员能让快速上手。

      Digg:PBDigg

      PBDigg是基于PHP+MYSQL的开源Digg社区资讯系统,融合了社会性标签、主题评论、Rss订阅等多种WEB2.0元素,是一个高效、快速的网站解决方案。

      Wiki:HDWiki

      HDWiki是专为中文用户设计和开发的开源、高效的中文百科建站解决方案,免费、易用、功能强大,和UCenter可无缝整合。

      RSS:IXNA

      IXNA是国内开源PHP新闻聚合程序,支持RSS多核心切换,默认支持lastrss、simplepie、magpierss,支持RDF、RSS、ATOM,支持智能识别。

      CMS:关于CMS的PHP产品很多,这里主要介绍下面三个。

      SupeSite

      SupeSite 是一套独立的内容管理系统(CMS),并且拥有对Discuz!论坛信息和UCenter Home个人空间信息聚合的功能,是一个不错的社区门户解决方案。

      DedeCMS

      DedeCMS是一个比较老的PHP CMS系统,很多早期的用户都是使用这个建立网站的。

      KingCMS

      KingCMS是一套简单易学,操作简单的开源内容管理系统(CMS),KingCMS分为PHP+MySQL和ASP+MSSQL/ACCESS两种语言版本的系统。

      最后是一次快讯,Twitter又无法访问了,估计XJ那里完事后可能会恢复,现在的解决方法在这里



      除非注明,月光博客文章均为原创,转载请以链接形式标明本文地址 

      本文地址:http://www.williamlong.info/archives/1853.html

    posted @ 2015-01-16 23:08 奋斗成就男人 阅读(201) | 评论 (0)编辑 收藏

    国外优秀开源PHP建站程序一览

    大量的PHP开源(开放源代码/Open Source)应用改变了这个世界,改变了互联网,以下我们总结从数据库到购物、博客等众多类型的开源PHP软件,供网站开发者们参考。

      博客:WordPress

      WordPress是使用PHP开发的著名博客平台,免费开源,功能强大,不仅仅用于博客搭建,还可以广泛应用于各类网络信息发布平台。

      论坛:phpBB

      phpBB是一种广泛流行的开源论坛软件,具有易于使用的管理面板和友好的用户安装界面,可以轻松地在数分钟内建立起一个论坛,功能上具有很高的可配置性,能够完全定制出相当个性化的论坛。

      CMS:Drupal

      Drupal是一个开源的内容管理系统(CMS)平台,拥有强大并可自由配置的功能,能支持从个人博客到大型社区驱动的网站等各种不同应用的网站项目。

      Wiki:MediaWiki

      MediaWiki是PHP语言写成开源Wiki引擎,全世界最大的Wiki项目维基百科就是使用MediaWiki引擎。

      Digg:Pligg

      Pligg是一套灵活的类似Digg的Web2.0 CMS系统,系统使用PHP开发,模仿了国外流行的DIGG系统。

      图像:Gallery

      Gallery 是一个非常有名的免费开源图库相册软件,基于 PHP 和 MySQL, PostgreSQL 等数据库。功能非常强大,有丰富的扩展可以下载,安装很简单,有很多插件可用。

      RSS:Gregarius

      Gregarius是一个RSS聚合程序,免费开源,具备不错的用户体验,易于操作和管理。可以把其当成RSS阅读器使用。

      电子商务:osCommerce

      osCommerce是一套由自由软件开发社团开发并维护的在线商店的解决方案,免费开源,并可以应用到任何的商业环境中,可以在短时间内生成一个功能强大的电子商务网站。

      广告:OpenX

      OpenX(原名phpAdsNew)是一个用PHP开发的广告管理与跟踪系统,适合各类网站使用,能够管理每个广告主拥有的多种任何尺寸横幅广告,按天查看,详细和概要统计并通过电子邮件发送报表给广告主。

      微博客:Laconica

      Laconica是一个开源的微型博客系统,也是一个Twitter克隆,可以实现Microblog的常用功能,国外不少微博客系统都是通过这个开源系统架设的。

      英文原文:Top Ten Open Source PHP Apps

    posted @ 2015-01-16 23:07 奋斗成就男人 阅读(259) | 评论 (0)编辑 收藏

    js调用php和php调用js的方法举例

    1 JS方式调用PHP文件并取得php中的值

     

    举一个简单的例子来说明:

    如在页面a.html中用下面这句调用:

     

    <script type="text/javascript" src="b.php?action=test"></script>

    <script type="text/javascript" >

    alert(jstext);

    </script>

     

     

    在b.php中有这样一段PHP代码:

    <? $action=$_GET['action']; //echo "var jstext='$action'"; //输出一句JS语句,生成一个JS变量,并赋颠值为PHP变量 $action的值 //echo "var jstext='aa'"; echo "var jstext="."'$action'"; ?>

     

     

    当执行a.html文件时,就会调用b.php文件,并将b.php文件的输出作为JS语句来执行,所以此处会弹出一个提示框,内容为JS变量jstext的值,也就是在PHP文件中赋给jstext的值.

    小结:

          在HTML里用JS 调用文件的方式调PHP文件,则PHP文件的输出将会被调用页作为JS的代码来用.

     

     

    2 php调用js中的值

    在z.php页面中有这样一段代码:

    <script type="text/javascript" > var url="aaaa*"; </script> <? $key="<script type=text/javascript>document.write(url)</script>"; echo $key; ?>

     

     

    3 php调用js中的方法(函数)

    <script type="text/javascript"> function test() {   var t1=3;   t1 = t1+2;   alert(t1);   //return t1; } </script>
    <?php echo "<script type='text/javascript'>test();</script>"; ?>

     

    4 JS调用PHP变量

    (1)

    <?php
    $userId=100;
    ?> <script>
    var userId;
    userId=document.getElementByIdx_x_x_x("userId").value;
    alert (userId);
    </script>
    <input type="text" name="userId" id="userId" value="<?php echo $userId; ?>">

    (2)

    <?php
    $url = '变化的网址';    //定义变量
    ?>
    <script type="text/javascript">
    //js调用php变量
    var ds ="<?php echo $url?>" ; //赋值 alert(ds); //输出效果 </script>

    5  -------------------------------

    <script language="JavaScript"> <!--

    var Y=<?php echo date('Y')?>,M=<?php echo date('n')?>,D=<?php echo date('j')?>;

    -->

    </script>

     

    6 自己写的js和php互相调用

    1.php内容:

    <?php

     

    //echo "<script LANGUAGE='javascript'>alert('$php变量');</script>";   //最简单的php调用js

    //echo "<a href=#><img width=50 src='$fruit_pic_array[$i]' onMouseOver=’javascript:a();‘></a>";

    //echo "<a href='3.php'>aaaa</a>";   //php中超链接

     

    //echo "<script type='text/javascript' language='javascript'>phpmake('PHP建站学习笔记网');</script>";   //有时候需要在PHP执行过程中,需要调用JavaScript自定义函数(验证时出错)

    echo "function ok(msg){alert(msg);}";

    ?>

    <HTML>

    <HEAD>

    <TITLE> php调用js文件的好办法</TITLE>

    </HEAD>

    <BODY>

    <!--js调用php中定义的js-->

    <scrīpt language=''javascrīpt'' type=''text/javascrīpt'' src=''1.php''></scrīpt>  

    <scrīpt>

    ok("aaaaaa!");

    </scrīpt>

    </script>

    </BODY>

    </HTML>

     

    2.php内容:

    <!--js调用php-->

    <?php

     

    $userId=100;

     

    ?>

     

    <script>

     

    var userId;

     

    userId=document.getElementByIdx_x("userId").value;

     

    alert (userId);

     

    </script>

     

    <input type="text" name="userId" id="userId" value="<?php echo $userId; ?>">

     

     

     

    <!--js调用php-->

    <?php

    if($_GET["action"]=="ok")

    {

    echo "I'm OK!";

    }

    else

    {

    echo "I'm not OK!";

    }

    ?>

    <SCRIPT Language = "JavaScript">

    function func()

    {

    if(confirm("Are you OK with this?"))

    {

    this.location = "ok.php?action=ok";

    }

    else

    {

    this.location = "ok.php?action=cancel";

    }

    }

    </SCRIPT>

    <html>

    <head>

    </head>

    <body>

    <a href="#" href="#" onClick="javascript:func();">Please Click</a>

    </body>

    </html>

     

    <!--js调用php-->

    <html>

    <head>

    <script>

    function isMail(PostString) 

    re=/\w*/ 

    if(re.test(PostString)) 

    return true; 

    else 

    return false; 

    function test(){

    if (isMail(<?php echo $email?>)) 

    {document.write("<?php echo "N";?>");} 

    else 

    {document.write('<?php echo 'Y';?>');}

    }

    </script>

    </head>

    <body>

    <?php 

    $email="aa"; 

    ?>

    <input   type=button   value=click   onclick= 'test() '>

    </body>

    </html>

     

    <!--php中含有js代码-->

    <?php

        echo   "

    <script   language=javascript>

      function   test(){

        alert( 'hello ');    

      }

    </script> ";

     

    ?>

    <input   type=button   value=click   onclick= 'test() '>

    posted @ 2015-01-16 01:45 奋斗成就男人 阅读(235) | 评论 (0)编辑 收藏

    PHP与JavaScript下的Cookie操作

         摘要: 下面的例子列出几种情形交互场景,列出JS和php交互的方法。总结下,以免日后再为cookie问题困扰。setcookie.php01<?php02    setcookie('php_cn_ck','php_中文_cookie');03    setcookie('php_en_ck','php_english_...  阅读全文

    posted @ 2015-01-15 19:16 奋斗成就男人 阅读(231) | 评论 (0)编辑 收藏

    PHP利用Curl、socket、file_get_contents POST数据

    <?php 
    /** 
    * Socket版本 
    * 使用方法: 
    * $post_string = "app=socket&version=beta"; 
    * request_by_socket('facebook.cn','/restServer.php',$post_string); 
    */ 
    function request_by_socket($remote_server,$remote_path,$post_string,$port 80,$timeout 30
    ){ 
        
    $socket fsockopen($remote_server,$port,$errno,$errstr,$timeout
    ); 
         if (!
    $socket) die("$errstr($errno)"
    ); 
        
        
    fwrite($socket,"POST $remote_path HTTP/1.0\r\n"
    ); 
        
    fwrite($socket,"User-Agent: Socket Example\r\n"
    ); 
        
    fwrite($socket,"HOST: $remote_server\r\n"
    ); 
        
    fwrite($socket,"Content-type: application/x-www-form-urlencoded\r\n"
    ); 
        
    fwrite($socket,"Content-length: ".strlen($post_string)+8."\r\n"
    ); 
        
    fwrite($socket,"Accept:*/*\r\n"
    ); 
        
    fwrite($socket,"\r\n"
    ); 
        
    fwrite($socket,"mypost=$post_string\r\n"
    ); 
        
    fwrite($socket,"\r\n"
    ); 
        
        
    $header ""

         while (
    $str trim(fgets($socket,4096
    ))) { 
            
    $header.=$str

         } 
        
        
    $data ""

         while (!
    feof($socket
    )) { 
            
    $data .= fgets($socket,4096
    ); 
         } 
        
         return 
    $data

    }

    /** 
    * Curl版本 
    * 使用方法: 
    * $post_string = "app=request&version=beta"; 
    * request_by_curl('http://facebook.cn/restServer.php',$post_string); 
    */ 
    function request_by_curl($remote_server,$post_string
    ){ 
        
    $ch curl_init
    (); 
        
    curl_setopt($ch,CURLOPT_URL,$remote_server
    ); 
        
    curl_setopt($ch,CURLOPT_POSTFIELDS,'mypost='.$post_string
    ); 
        
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true
    ); 
        
    curl_setopt($ch,CURLOPT_USERAGENT,"Jimmy's CURL Example beta"
    ); 
        
    $data curl_exec($ch
    ); 
        
    curl_close($ch
    ); 
         return 
    $data


    /** 
    * 其它版本 
    * 使用方法: 
    * $post_string = "app=request&version=beta"; 
    * request_by_other('http://facebook.cn/restServer.php',$post_string); 
    */ 
    function request_by_other($remote_server,$post_string
    ){ 
        
    $context 
    = array( 
            
    'http'
    =>array( 
                
    'method'=>'POST'

                
    'header'=>'Content-type: application/x-www-form-urlencoded'."\r\n"

                          
    'User-Agent : Jimmy\'s POST Example beta'."\r\n"

                          
    'Content-length: '.strlen($post_string)+8

                
    'content'=>'mypost='.$post_string

             ); 
        
    $stream_context stream_context_create($context
    ); 
        
    $data file_get_contents($remote_server,FALSE,$stream_context
    ); 
         return 
    $data

    }

    function curl_file_get_contents($durl) {     

            $ch = curl_init ();     
            curl_setopt ( $ch, CURLOPT_URL, $durl );        
            curl_setopt ( $ch, CURLOPT_POST, 1 );
            curl_setopt ( $ch, CURLOPT_TIMEOUT, 5 );        
            curl_setopt ( $ch, CURLOPT_USERAGENT, _USERAGENT_ );        
            curl_setopt ( $ch, CURLOPT_REFERER, _REFERER_ );        
            curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
            $r = curl_exec ( $ch );
            curl_close ( $ch );     
            return $r;

        }




    php读取网络文件 curl, fsockopen ,file_get_contents 几个方法的效率对比

    curl效率及稳定原来可以远远超越file_get_contents

     

    最近需要获取别人网站上的音乐数据。用了file_get_contents函数,但是总是会遇到获取失败的问题,尽管按照手册中的 例子设置了超时,可多数时候不会奏效:


    $config['context'] = stream_context_create(array(‘http’ => array(‘method’ => “GET”,
       ’timeout’ => 5//这个超时时间不稳定,经常不奏效
       )
      ));

    这时候,看一下服务器的连接池,会发现一堆类似的错误,让我头疼万分:
    file_get_contents(http://***): failed to open stream…

    现在改用了curl库,写了一个函数替换:
    function curl_file_get_contents($durl){
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $durl);
      curl_setopt($ch, CURLOPT_TIMEOUT, 5);
      curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
      curl_setopt($ch, CURLOPT_REFERER,_REFERER_);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      $r = curl_exec($ch);
      curl_close($ch);
       return $r;
    }

    如此,除了真正的网络问题外,没再出现任何问题。
    这是别人做过的关于curl和file_get_contents的测试:
    file_get_contents抓取google.com需用秒数:

     

    2.31319094

    2.30374217
    2.21512604
    3.30553889
    2.30124092

    curl使用的时间:

     

    0.68719101

    0.64675593
    0.64326
    0.81983113
    0.63956594

    差距很大?呵呵,从我使用的经验来说,这两个工具不只是速度有差异,稳定性也相差很大。

    建议对网络数据抓取稳定性要求比较高的朋友使用上面的 curl_file_get_contents函数,不但稳定速度快,还能假冒浏览器欺骗目标地址哦!

     

     

     

    看到的其他文章收藏于此===============================

    php fsockopen

    方法1: 用file_get_contents 以get方式获取内容
    <?php
    $url='http://www.domain.com/';
    $html = file_get_contents($url);
    echo $html;
    ?>

    方法2: 用fopen打开url, 以get方式获取内容
    <?php
    $fp = fopen($url, 'r');
    stream_get_meta_data($fp);
    while(!feof($fp)) {
    $result .= fgets($fp, 1024);
    }
    echo "url body: $result";
    fclose($fp);
    ?>



    方法3:用file_get_contents函数,以post方式获取url
    <?php
    $data = array ('foo' => 'bar');
    $data = http_build_query($data);

    $opts = array (
    'http' => array (
    'method' => 'POST',
    'header'=> "Content-type: application/x-www-form-urlencoded\r\n" .
    "Content-Length: " . strlen($data) . "\r\n",
    'content' => $data
    )
    );

    $context = stream_context_create($opts);
    $html = file_get_contents('http://localhost/e/admin/test.html', false, $context);

    echo $html;
    ?>


    方法4:用fsockopen函数打开url,以get方式获取完整的数据,包括header和body

    <?php
    function get_url ($url,$cookie=false)
    {
    $url = parse_url($url);
    $query = $url[path]."?".$url[query];
    echo "Query:".$query;
    $fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30);
    if (!$fp) {
    return false;
    } else {
    $request = "GET $query HTTP/1.1\r\n";
    $request .= "Host: $url[host]\r\n";
    $request .= "Connection: Close\r\n";
    if($cookie) $request.="Cookie:   $cookie\n";
    $request.="\r\n";
    fwrite($fp,$request);
    while()) {
    $result .= @fgets($fp, 1024);
    }
    fclose($fp);
    return $result;
    }
    }
    //获取url的html部分,去掉header
    function GetUrlHTML($url,$cookie=false)
    {
    $rowdata = get_url($url,$cookie);
    if($rowdata)
    {
    $body= stristr($rowdata,"\r\n\r\n");
    $body=substr($body,4,strlen($body));
    return $body;
    }

        return false;
    }
    ?>



    方法5:用fsockopen函数打开url,以POST方式获取完整的数据,包括header和body

    <?php
    function HTTP_Post($URL,$data,$cookie, $referrer="")
    {

        // parsing the given URL
    $URL_Info=parse_url($URL);

        // Building referrer
    if($referrer=="") // if not given use this script as referrer
    $referrer="111";

        // making string from $data
    foreach($data as $key=>$value)
    $values[]="$key=".urlencode($value);
    $data_string=implode("&",$values);

        // Find out which port is needed - if not given use standard (=80)
    if(!isset($URL_Info["port"]))
    $URL_Info["port"]=80;

        // building POST-request:
    $request.="POST ".$URL_Info["path"]." HTTP/1.1\n";
    $request.="Host: ".$URL_Info["host"]."\n";
    $request.="Referer: $referer\n";
    $request.="Content-type: application/x-www-form-urlencoded\n";
    $request.="Content-length: ".strlen($data_string)."\n";
    $request.="Connection: close\n";

        $request.="Cookie:   $cookie\n";

        $request.="\n";
    $request.=$data_string."\n";

        $fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
    fputs($fp, $request);
    while(!feof($fp)) {
    $result .= fgets($fp, 1024);
    }
    fclose($fp);

        return $result;
    }

    ?>


    方法6:使用curl库,使用curl库之前,可能需要查看一下php.ini是否已经打开了curl扩展

    <?php
    $ch = curl_init();
    $timeout = 5;
    curl_setopt ($ch, CURLOPT_URL, 'http://www.domain.com/');
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $file_contents = curl_exec($ch);
    curl_close($ch);

    echo $file_contents;
    ?>

     

     

     

     

    php中 curl, fsockopen ,file_get_contents 三个函数 都可以实现采集模拟发言 。 三者有什么区别,或者讲究么  

    赵永斌:
    有些时候用file_get_contents()调用外部文件,容易超时报错。换成curl后就可以.具体原因不清楚
    curl 效率比file_get_contents()和fsockopen()高一些,原因是CURL会自动对DNS信息进行缓存(亮点啊 有我待亲测)

    范佳鹏:
    file_get_contents curl fsockopen
    在当前所请求环境下选择性操作,没有一概而论:
    具我们公司开发KBI应用来看:
    刚开始采用:file_get_contents
    后来采用:fsockopen
    最后到至今采用:curl

    (远程)我个人理解到的表述如下(不对请指出,不到位请补充)
    file_get_contents 需要php.ini里开启allow_url_fopen,请求http时,使用的是http_fopen_wrapper,不会keeplive.curl是可以的。
    file_get_contents()单个执行效率高,返回没有头的信息。
    这个是读取一般文件的时候并没有什么问题,但是在读取远程问题的时候就会出现问题。
    如果是要打一个持续连接,多次请求多个页面。那么file_get_contents和fopen就会出问题。
    取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。
    sock较底层,配置麻烦,不易操作。 返回完整信息。

    潘少宁-腾讯:

    file_get_contents 虽然可以获得某URL的内容,但不能post  get啊。
    curl 则可以post和get啊。还可以获得head信息
    而socket则更底层。可以设置基于UDP或是TCP协议去交互
    file_get_contents 和 curl 能干的,socket都能干。
    socket能干的,curl 就不一定能干了
    file_get_contents  更多的时候 只是去拉取数据。效率比较高  也比较简单。
    赵的情况这个我也遇到过,我通过CURL设置host 就OK了。  这和网络环境有关系

    posted @ 2014-12-31 19:05 奋斗成就男人 阅读(310) | 评论 (0)编辑 收藏

    php的curl和socket的区别

    首先说下啥是socket:
           php使用berkely的socket库来创建他的连接,socket是一个数据结果,你可以通过这个socket来开启服务器和客户端的会话。服务器端一直处于监听状态,当一个客户端连接服务器,他就打开服务器端正在监听的一个端口进行会话。这时服务器端接收客户端的连接请求,那么就进行一次循环。现在这个客户端就能够发送信息到服务器,服务器也可以发送信息给客户端。
          产生一个socket你一共需要三个变量:
         1、一个协议
         2、一个socket类型
         3、一个公共协议类型
         以下是对这三个变量的详细解释,大概了解下吧
         协议:产生一个socket有三个协议供选择:
        1、AF_INET  这个是使用比较广泛的产生socket的协议,使用tcp或者udp协议传输,使用ipv4地址
        2、AF_INET6 显而易见哈,同上,不同的是使用ipv6地址
        3、AF_UNIX  使用在unix或者linux机器上,这个很少使用,仅在服务器端和客户端均为unix或者linux系统上使用。
       
         socket类型:
         1、SOCK_STREAM  这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
         2、SOCK_DGRAM  这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
         3、SOCK_SEQPACKET  这个协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
         4、SOCK_RAW  这个socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
         5、SOCK_RDM  这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序
         
         公共协议类型:
        1、ICMP (Internet Control Message Protocol)互联网控制报文协议,主要用在网关和主机上,用来检测网络状况和报告错误信息
        2、TCP  (Transmission Control Protocol) 传输控制协议,他是使用最广泛的协议,他能够保证数据包到达接收者那里,如果中途出现错误,那么此协议从新发送数据包。
       3、UDP   (User Datagram Protocol)用户数据包协议,他是无连接的,不可靠的数据传输协议。

       好啦,你现在知道了产生一个socke需要三个元素,那么在php中socket_create()就需要三个参数,一个协议,一个socket类型,一个公共协议。如果创建成功,socket_create()返回一个socket资源类型,如果不成功,嘿嘿,那你会收到一个false.
        
    CURL
    cURL  是利用URL语法规定来传输文件和数据的工具。他支持HTTP、FTP、TELNET。
        为啥要使用cURL呢?
       因为,如果我们有时候想灵活的获取网页上的内容,例如处理coockies、验证、表单提交、文件上传等等等等。那么你就需要用到cURL.据说php有着功能强大的cURL库(因为偶也说不清强大在哪里啦,
        php使用cURL的选项基本步骤如下:
        1、初始化
        2、参数设置
        3、页面内容获取或者操作
        4、释放句柄

    看看下面这个简单的例子吧。
    <?php  
    //初始化curl  
    $ch = curl_init ();  
    /* 
     * 设置curl 
     * php手册对于curl_setopt的解释为:设置对于curl传输的操作 
     * curl_setopt有三个参数:资源(一般为你建立的curl句柄)、操作(你将对这个句柄作何操作)、参数(对于这个操作你给出的参数) 
     
    */  
    //例如你想对百度进行某些操作  
    curl_setopt ( $ch, CURLOPT_URL, "http://www.baidu.com");  
    //现在看来你要向百度post数据  
    curl_setopt ( $ch, CURLOPT_POST, 1 );  
    /*给出了要post的数据:$post_string,post的数据可以是一个文件, 
    *那么你需要以@加上文件的全路径给出,或者你要post一些数据, 
    *那么你可以按照数组形式给出,或者按照字符串给出, 
    *如果你想按照字符串形式给出,请把字符串urlencode,嘿嘿 
    */  
    curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_string );  
    /* 
     *把curl操作的结果以字符串形式 从curl_exec ()返回,而不是直接就输出了 
     
    */  
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );  
    //得到操作返回结果  
    $result = curl_exec ( $ch );  
    //关闭curl句柄  
    curl_close ( $ch );   
    ?>  
    因为php的curl有很多操作,要都记住估计很困难,反正偶记不住啦,说些大家可能用的上的吧。大笑
    获取服务器的一些信息
    [php] view plaincopy
    <?php  
      
      
    //初始化curl  
    $ch = curl_init ();  
      
    curl_setopt ( $ch, CURLOPT_URL, "http://www.baidu.com");  
    curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );  
    curl_exec($ch);  
    $info = curl_getinfo($ch);  
      
    var_dump($info);  
    ?>  

    通过上面的例子,你将会获得如下信息:
    “url” //资源网络地址
    “content_type” //内容编码
    “http_code” //HTTP状态码
    “header_size” //header的大小
    “request_size” //请求的大小
    “filetime” //文件创建时间
    “ssl_verify_result” //SSL验证结果
    “redirect_count” //跳转技术  
    “total_time” //总耗时
    “namelookup_time” //DNS查询耗时
    “connect_time” //等待连接耗时
    “pretransfer_time” //传输前准备耗时
    “size_upload” //上传数据的大小
    “size_download” //下载数据的大小
    “speed_download” //下载速度
    “speed_upload” //上传速度
    “download_content_length”//下载内容的长度
    “upload_content_length” //上传内容的长度  
    “starttransfer_time” //开始传输的时间
    “redirect_time”//重定向耗时

    利用curl你还可以做以下操作:
    模拟页面的post操作
    文件上传
    HTTP 认证
    FTP 上传
    回调函数
    以上关于curl的大前提是你的php在安装编译时加了 --with-curlwrappers ,你可以通过phpinfo()操作来查看你是不是在编译时加了这个扩展库。
    如果加载了这个扩展,你将能看见类似:
    如果你没有这个扩展,你需要改一下php.ini文件,去掉extension=php_curl.dll前面的分号。
    好啦,现在我们知道socket和curl是咋回事了,socket是一种数据结构,他可以用来在服务器和客户端进行对话。而curl是利用url语法规定来传输文件和数据的规定,支持很多协议,例如FTP,HTTP、TELNET等。

    posted @ 2014-12-31 19:03 奋斗成就男人 阅读(505) | 评论 (0)编辑 收藏

    php中使用Curl、socket、file_get_contents三种方法POST提交数据

    抓取远程内容,之前一直都在用file_get_content函数,其实早就知道有curl这么一个好东西的存在,但是看了一眼后感觉使用颇有些复杂,没有file_get_content那么简单,再就是需求也不大,所以没有学习使用curl。
    直到最近,要做一个网页小偷程序的时候才发现file_get_content已经完全不能满足需求了。我觉得,在读取远程内容的时候,file_get_content除了使用比curl便捷以外,其他都没有curl好。

    php中curl和file_get_content的一些比较

    主要区别:

    学习才发现,curl支持很多协议,有FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE以及LDAP,也就是说,它能做到很多file_get_content做不到的事情。curl在php可以实现远程获取和采集内容;实现PHP网页版的FTP上传下载;实现模拟登陆;实现接口对接(API),数据传输;实现模拟Cookie;下载文件断点续传等等,功能十分强大。

    了解curl一些基本的使用后,才发现其实并不难,只不过记住里面一些设置参数,难弄一点,但是我们记住几个常用的就可以了。

    开启curl:

    因为PHP默认是不支持curl功能的,因此如果要用curl的话,首先需要在php.ini中开启该功能,即去掉 ;extension= php_curl.dll 前面的分号,然后保存后重启apache/iis就好了。

    基本语法:

    复制代码代码如下:

    $my_curl = curl_init();    //初始化一个curl对象
    curl_setopt($my_curl, CURLOPT_URL, "http://www.jb51.net");    //设置你需要抓取的URL
    curl_setopt($my_curl,CURLOPT_RETURNTRANSFER,1);    //设置是将结果保存到字符串中还是输出到屏幕上,1表示将结果保存到字符串
    $str = curl_exec($curl);    //执行请求
    echo $str;    //输出抓取的结果
    curl_close($curl);    //关闭url请求

    最近需要获取别人网站上的音乐数据。用了file_get_contents函数,但是总是会遇到获取失败的问题,尽管按照手册中的例子设置了超时,可多数时候不会奏效:

    $config['context'] = stream_context_create(array('http' => array('method' => "GET",
    'timeout' => 5//这个超时时间不稳定,经常不奏效
    )
    ));

    这时候,看一下服务器的连接池,会发现一堆类似的错误,让我头疼万分:
    file_get_contents(http://***): failed to open stream…

    现在改用了curl库,写了一个函数替换:
    function curl_file_get_contents($durl){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $durl);
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
    curl_setopt($ch, CURLOPT_REFERER,_REFERER_);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $r = curl_exec($ch);
    curl_close($ch);
    return $r;
    }

    如此,除了真正的网络问题外,没再出现任何问题。
    这是别人做过的关于curl和file_get_contents的测试:
    file_get_contents抓取google.com需用秒数:

    2.31319094
    2.30374217
    2.21512604
    3.30553889
    2.30124092

    curl使用的时间:

    0.68719101
    0.64675593
    0.64326
    0.81983113
    0.63956594

    差距很大?呵呵,从我使用的经验来说,这两个工具不只是速度有差异,稳定性也相差很大。

    建议对网络数据抓取稳定性要求比较高的朋友使用上面的 curl_file_get_contents函数,不但稳定速度快,还能假冒浏览器欺骗目标地址哦!

    方法1: 用file_get_contents 以get方式获取内容

    复制代码代码如下:

    <?php
    $url='http://www.domain.com/';
    $html = file_get_contents($url);
    echo $html;
    ?>

    方法2: 用fopen打开url, 以get方式获取内容

    复制代码代码如下:

    <?php
    $fp = fopen($url, 'r');
    stream_get_meta_data($fp);
    while(!feof($fp)) {
    $result .= fgets($fp, 1024);
    }
    echo "url body: $result";
    fclose($fp);
    ?>

    方法3:用file_get_contents函数,以post方式获取url

    复制代码代码如下:

    <?php
    $data = array ('foo' => 'bar');
    $data = http_build_query($data);

    $opts = array (
    'http' => array (
    'method' => 'POST',
    'header'=> "Content-type: application/x-www-form-urlencodedrn" .
    "Content-Length: " . strlen($data) . "rn",
    'content' => $data
    )
    );
    $context = stream_context_create($opts);
    $html = file_get_contents('http://localhost/e/admin/test.html', false, $context);
    echo $html;
    ?>

    方法4:用fsockopen函数打开url,以get方式获取完整的数据,包括header和body

    复制代码代码如下:

    <?php
    function get_url ($url,$cookie=false)
    {
    $url = parse_url($url);
    $query = $url[path]."?".$url[query];
    echo "Query:".$query;
    $fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30);
    if (!$fp) {
    return false;
    } else {
    $request = "GET $query HTTP/1.1rn";
    $request .= "Host: $url[host]rn";
    $request .= "Connection: Closern";
    if($cookie) $request.="Cookie: $cookien";
    $request.="rn";
    fwrite($fp,$request);
    while()) {
    $result .= @fgets($fp, 1024);
    }
    fclose($fp);
    return $result;
    }
    }
    //获取url的html部分,去掉header
    function GetUrlHTML($url,$cookie=false)
    {
    $rowdata = get_url($url,$cookie);
    if($rowdata)
    {
    $body= stristr($rowdata,"rnrn");
    $body=substr($body,4,strlen($body));
    return $body;
    }
    return false;
    }
    ?>

    方法5:用fsockopen函数打开url,以POST方式获取完整的数据,包括header和body

    复制代码代码如下:

    <?php
    function HTTP_Post($URL,$data,$cookie, $referrer="")
    {
    // parsing the given URL
    $URL_Info=parse_url($URL);

    // Building referrer
    if($referrer=="") // if not given use this script as referrer
    $referrer="111″;

    // making string from $data
    foreach($data as $key=>$value)
    $values[]="$key=".urlencode($value);
    $data_string=implode("&",$values);

    // Find out which port is needed – if not given use standard (=80)
    if(!isset($URL_Info["port"]))
    $URL_Info["port"]=80;

    // building POST-request:
    $request.="POST ".$URL_Info["path"]." HTTP/1.1n";
    $request.="Host: ".$URL_Info["host"]."n";
    $request.="Referer: $referern";
    $request.="Content-type: application/x-www-form-urlencodedn";
    $request.="Content-length: ".strlen($data_string)."n";
    $request.="Connection: closen";

    $request.="Cookie: $cookien";

    $request.="n";
    $request.=$data_string."n";

    $fp = fsockopen($URL_Info["host"],$URL_Info["port"]);
    fputs($fp, $request);
    while(!feof($fp)) {
    $result .= fgets($fp, 1024);
    }
    fclose($fp);

    return $result;
    }
    ?>

    方法6:使用curl库,使用curl库之前,可能需要查看一下php.ini是否已经打开了curl扩展

    复制代码代码如下:

    <?php
    $ch = curl_init();
    $timeout = 5;
    curl_setopt ($ch, CURLOPT_URL, 'http://www.domain.com/');
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $file_contents = curl_exec($ch);
    curl_close($ch);
    echo $file_contents;
    ?>

    php中 curl, fsockopen ,file_get_contents 三个函数 都可以实现采集模拟发言 。三者有什么区别,或者讲究么

    赵永斌:
    有些时候用file_get_contents()调用外部文件,容易超时报错。换成curl后就可以.具体原因不清楚
    curl 效率比file_get_contents()和fsockopen()高一些,原因是CURL会自动对DNS信息进行缓存(亮点啊有我待亲测)

    范佳鹏:
    file_get_contents curl fsockopen
    在当前所请求环境下选择性操作,没有一概而论:
    具我们公司开发KBI应用来看:
    刚开始采用:file_get_contents
    后来采用:fsockopen
    最后到至今采用:curl

    (远程)我个人理解到的表述如下(不对请指出,不到位请补充)
    file_get_contents 需要php.ini里开启allow_url_fopen,请求http时,使用的是http_fopen_wrapper,不会keeplive.curl是可以的。
    file_get_contents()单个执行效率高,返回没有头的信息。
    这个是读取一般文件的时候并没有什么问题,但是在读取远程问题的时候就会出现问题。
    如果是要打一个持续连接,多次请求多个页面。那么file_get_contents和fopen就会出问题。
    取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。
    sock较底层,配置麻烦,不易操作。 返回完整信息。

    潘少宁-腾讯:
    file_get_contents 虽然可以获得某URL的内容,但不能post get啊。
    curl 则可以post和get啊。还可以获得head信息
    而socket则更底层。可以设置基于UDP或是TCP协议去交互
    file_get_contents 和 curl 能干的,socket都能干。
    socket能干的,curl 就不一定能干了
    file_get_contents 更多的时候 只是去拉取数据。效率比较高 也比较简单。
    赵的情况这个我也遇到过,我通过CURL设置host 就OK了。 这和网络环境有关系

    复制代码代码如下:

    <?php 
    /** 
    * Socket版本 
    * 使用方法: 
    * $post_string = "app=socket&version=beta"; 
    * request_by_socket('jb51.net','/restServer.php',$post_string); 
    */ 
    function request_by_socket($remote_server,$remote_path,$post_string,$port = 80,$timeout = 30){ 
    $socket = fsockopen($remote_server,$port,$errno,$errstr,$timeout); 
    if (!$socket) die("$errstr($errno)"); 
    fwrite($socket,"POST $remote_path HTTP/1.0"); 
    fwrite($socket,"User-Agent: Socket Example"); 
    fwrite($socket,"HOST: $remote_server"); 
    fwrite($socket,"Content-type: application/x-www-form-urlencoded"); 
    fwrite($socket,"Content-length: ".strlen($post_string)+8.""); 
    fwrite($socket,"Accept:*/*"); 
    fwrite($socket,""); 
    fwrite($socket,"mypost=$post_string"); 
    fwrite($socket,""); 
    $header = ""; 
    while ($str = trim(fgets($socket,4096))) { 
    $header.=$str; 

    $data = ""; 
    while (!feof($socket)) { 
    $data .= fgets($socket,4096); 

    return $data; 

    /** 
    * Curl版本 
    * 使用方法: 
    * $post_string = "app=request&version=beta"; 
    * request_by_curl('http://jb51.net/restServer.php',$post_string); 
    */ 
    function request_by_curl($remote_server,$post_string){ 
    $ch = curl_init(); 
    curl_setopt($ch,CURLOPT_URL,$remote_server); 
    curl_setopt($ch,CURLOPT_POSTFIELDS,'mypost='.$post_string); 
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); 
    curl_setopt($ch,CURLOPT_USERAGENT,"Jimmy's CURL Example beta"); 
    $data = curl_exec($ch); 
    curl_close($ch); 
    return $data; 

    /** 
    * 其它版本 
    * 使用方法: 
    * $post_string = "app=request&version=beta"; 
    * request_by_other('http://jb51.net/restServer.php',$post_string); 
    */ 
    function request_by_other($remote_server,$post_string){ 
    $context = array( 
    'http'=>array( 
    'method'=>'POST', 
    'header'=>'Content-type: application/x-www-form-urlencoded'."". 
    'User-Agent : Jimmy's POST Example beta'."". 
    'Content-length: '.strlen($post_string)+8, 
    'content'=>'mypost='.$post_string) 
    ); 
    $stream_context = stream_context_create($context); 
    $data = file_get_contents($remote_server,FALSE,$stream_context); 
    return $data; 

    ?> 

    posted @ 2014-12-31 18:59 奋斗成就男人 阅读(649) | 评论 (0)编辑 收藏

    怎么用PHP发送HTTP请求(POST请求、GET请求)?

    /**
     * 发送post请求
     * 
    @param string $url 请求地址
     * 
    @param array $post_data post键值对数据
     * 
    @return string
     
    */
    function send_post($url, $post_data) {

        $postdata = http_build_query($post_data);
        $options = array(
            'http' =>; array(
                'method' =>; 'POST',
                'header' =>; 'Content-type:application/x-www-form-urlencoded',
                'content' =>; $postdata,
                'timeout' =>; 15 * 60 // 超时时间(单位:s)
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);

        return $result;
    }

    使用如下:
    post_data = array(
        'username' => 'stclair2201',
        'password' => 'handan'
    );
    send_post('http://blog.snsgou.com', $post_data);


    实战经验:

    当我利用上述代码给另一台服务器发送http请求时,发现,如果服务器处理请求时间过长,本地的PHP会中断请求,即所谓的超时中断,第一个怀疑的是PHP本身执行时间的超过限制,但想想也不应该,因为老早就按照这篇文章设置了“PHP执行时间限制”(【推荐】PHP上传文件大小限制大全 ),仔细琢磨,想想,应该是http请求本身的一个时间限制,于是乎,就想到了怎么给http请求时间限制搞大一点。。。。。。查看PHP手册,果真有个参数 “ timeout ”,默认不知道多大,当把它的值设大一点,问题得已解决


    Socket版本:

    /**
     * Socket版本
     * 使用方法:
     * $post_string = "app=socket&amp;version=beta";
     * request_by_socket('blog.snsgou.com', '/restServer.php', $post_string);
     
    */
    function request_by_socket($remote_server,$remote_path,$post_string,$port = 80,$timeout = 30) {
        $socket = fsockopen($remote_server, $port, $errno, $errstr, $timeout);
        if (!$socket) die("$errstr($errno)");
        fwrite($socket, "POST $remote_path HTTP/1.0");
        fwrite($socket, "User-Agent: Socket Example");
        fwrite($socket, "HOST: $remote_server");
        fwrite($socket, "Content-type: application/x-www-form-urlencoded");
        fwrite($socket, "Content-length: " . (strlen($post_string) + 8) . "");
        fwrite($socket, "Accept:*/*");
        fwrite($socket, "");
        fwrite($socket, "mypost=$post_string");
        fwrite($socket, "");
        $header = "";
        while ($str = trim(fgets($socket, 4096))) {
            $header .= $str;
        }

        $data = "";
        while (!feof($socket)) {
            $data .= fgets($socket, 4096);
        }

        return $data;
    }

    Curl版本:
    /**
     * Curl版本
     * 使用方法:
     * $post_string = "app=request&version=beta";
     * request_by_curl('
    http://blog.snsgou.com/restServer.php', $post_string);
     
    */
    function request_by_curl($remote_server, $post_string) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $remote_server);
        curl_setopt($ch, CURLOPT_POSTFIELDS, 'mypost=' . $post_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_USERAGENT, "snsgou.com's CURL Example beta");
        $data = curl_exec($ch);
        curl_close($ch);

        return $data;
    }

    Curl版本(2)

    /**
     * 发送HTTP请求
     *
     * 
    @param string $url 请求地址
     * 
    @param string $method 请求方式 GET/POST
     * 
    @param string $refererUrl 请求来源地址
     * 
    @param array $data 发送数据
     * 
    @param string $contentType 
     * 
    @param string $timeout
     * 
    @param string $proxy
     * 
    @return boolean
     
    */
    function send_request($url, $data, $refererUrl = '', $method = 'GET', $contentType = 'application/json', $timeout = 30, $proxy = false) {
        $ch = null;
        if('POST' === strtoupper($method)) {
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_HEADER,0 );
            curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            if ($refererUrl) {
                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
            }
            if($contentType) {
                curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:'.$contentType));
            }
            if(is_string($data)){
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            }
        } else if('GET' === strtoupper($method)) {
            if(is_string($data)) {
                $real_url = $url. (strpos($url, '?') === false ? '?' : ''). $data;
            } else {
                $real_url = $url. (strpos($url, '?') === false ? '?' : ''). http_build_query($data);
            }

            $ch = curl_init($real_url);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:'.$contentType));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            if ($refererUrl) {
                curl_setopt($ch, CURLOPT_REFERER, $refererUrl);
            }
        } else {
            $args = func_get_args();
            return false;
        }

        if($proxy) {
            curl_setopt($ch, CURLOPT_PROXY, $proxy);
        }
        $ret = curl_exec($ch);
        $info = curl_getinfo($ch);
        $contents = array(
                'httpInfo' => array(
                        'send' => $data,
                        'url' => $url,
                        'ret' => $ret,
                        'http' => $info,
                )
        );

        curl_close($ch);
        return $ret;
    }
    调用 WCF接口 的一个例子:$json = restRequest($r_url,'POST', json_encode($data));

    posted @ 2014-12-31 18:57 奋斗成就男人 阅读(476) | 评论 (0)编辑 收藏