php soap 实例 不使用wsdl

 更新时间:2016年11月25日 16:09  点击:1483

Server+Client

 

上篇用了wsdl这个写不用wsdl.

 

声明:很简单!!!!!!

参考了如下:

http://blog.111cn.net/phphot/archive/2007/07/15/1692109.aspx

 

类文件

 

<?php

/**

* 实现业务逻辑的类,此类是一个普通类

*

*/

class Basic {

       /**

        * 返回一个字符串:Hello World!

        *

        * @return string

        */

       public function returnString($test){

               return "Hello World!".$test;

       }

}

?>

Server

 

<?php

/**

* Web ServiceServer端,包含类文件。

*/

require_once("basic.php");

/**

* 创建Server对象

*/

$arrOptions = array(''uri''=>''checkAPI'');    //设置命名空间

$objSoapServer = new SoapServer(null,$arrOptions);

/**

* 注册Basic类的所有方法

*/

$objSoapServer->setClass("Basic");

/**

* 处理请求

*/

$objSoapServer->handle();

?>

 

Client

 

<?php

/**

* Client端,首先创建Client对象

*/

$arrOptions = array(''uri''=>''checkAPI'',                     //设置命名空间

                       ''location''=>''http://localhost/user/soaptest.php'',        //设置Server地址

                       ''trace''=>true);

$objSoapClient = new SoapClient(null,$arrOptions);

/**

* 远程调用

*/

$test=''ok123'';

try{

   $strReturn = $objSoapClient->returnString($test);

}catch(Exception $e){

}

/**

* 打印结果

*/

echo $strReturn;

?>

  Server+Client+WSDL

 

声明:很简单!!!!!!

参考了如下:

 

先建Server,然后使用wsdl工具来生成wsdl,我用的是zend development environment,

zde中的tools中的wsdl generator wizard

第一页是名字,和输出地址(输出后直接挪过去就OK)

第二页是类和地址,类挑上勾,URL那里添server那个文件的地址

第三页 finish

别忘了拷那个wsdl过去...

 

记得server引用的那个类文件里不要有输出.

 

一共有两个需要添地址的地方

一个是wsdl中的描述http://127.0.0.1/test/CulculatorServer.php

一个是client中的连接http://127.0.0.1/test/Culculator.wsd

 

类文件

 

<?php

/**

 * @name Culculator.php

 * @date Fri Jan 25 12:43:40 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

 

class Culculator

{

       /**

        * 求和

        *

        * @param float $x

        * @param float $y

        * @return float

        */

       public function add($x, $y)

       {

              return $x + $y;

       }

}

?>

 

Server

 

<?php

/**

 * @name CulculatorServer.php

 * @date Fri Jan 25 12:44:04 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

 

include(''./Culculator.php'');

$server = new SoapServer(''./Culculator.wsdl'');

$server->setClass(''Culculator'');

$server->handle();

?>

 

Client

 

<?php

/**

 * @name CulculatorClient.php

 * @date Fri Jan 25 12:43:54 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

 

$soap = new SoapClient(''http://127.0.0.1/test/Culculator.wsdl'');

echo $soap->add(1, 2);

?>

 

WSDL

 

<?xml version=''1.0'' encoding=''UTF-8''?>

 

<!-- WSDL file generated by Zend Studio. -->

 

<definitions name="math" targetNamespace="urn:math" xmlns:typens="urn:math" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">

       <message name="add">

              <part name="x" type="xsd:float"/>

              <part name="y" type="xsd:float"/>

       </message>

       <message name="addResponse">

              <part name="addReturn" type="xsd:float"/>

       </message>

       <portType name="CulculatorPortType">

              <operation name="add">

                     <documentation>

                            求和

                     </documentation>

                     <input message="typens:add"/>

                     <output message="typens:addResponse"/>

              </operation>

       </portType>

       <binding name="CulculatorBinding" type="typens:CulculatorPortType">

              <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

              <operation name="add">

                     <soap:operation soapAction="urn:CulculatorAction"/>

                     <input>

                            <soap:body namespace="urn:math" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

                     </input>

                     <output>

                            <soap:body namespace="urn:math" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>

                     </output>

              </operation>

       </binding>

       <service name="mathService">

              <port name="CulculatorPort" binding="typens:CulculatorBinding">

                     <soap:address location="http://127.0.0.1/test/CulculatorServer.php"/>

              </port>

       </service>

</definitions>

 fsockopen

socket方式打开一个连接

我最常用的是模拟post

这个是小李挖掘的到的...不错

至于要模拟get方式....直接file_get_content就行了.

代码见后面

 

stream_socket_client, 代码见后面

这个和fsockopenfsockopen一样.socket方式打开一个连接,只是参数不同

 

stream_socket_server

建立一个socket server, 代码见后面

如果是建立的是tcpserver 就用stream_socket_accept进行通讯

如果是建立的是udpserver 就用stream_socket_recvfromstream_socket_sendto进行通讯,而且stream_socket_server中需要加个参数STREAM_SERVER_BIND

 

还有个socket扩展,这个是最基础的建立socket,但是从5.3.0开始就放到pecl中了.

这里就不介绍了.

 

---------------------------- stream_socket client---------------------------

 

<?php

/**

 * @name test.php

 * @date Sun Jan 27 00:49:00 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

 

$xport = "tcp";

$port = "8001";

$ip = "127.0.0.1";

$address = "{$xport}://{$ip}:{$port}";

$fp = stream_socket_client($address, $errno, $errstr, 1);

if (!$fp) {

    echo "$errstr ($errno)<br /> ";

} else {

    fwrite($fp, " ");

    echo fread($fp, 1024);

    fclose($fp);

}

?>

 

---------------------------- streamSocketServer---------------------------

 

<?php

/**

 * @name test2.php

 * @date Sun Jan 27 00:45:57 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

header("Content-type: text/html;charset=utf-8");

//设置不超时.服务端当然不能超时

set_time_limit(0);

//得到可用socket

$xportlist = stream_get_transports();

echo "transports: ";

foreach ($xportlist as $value) {

       echo "{$value} ";

}

//定义一些东西

$xport = "tcp";

$port = "8001";

$address = "{$xport}://0.0.0.0:{$port}";

//建立socketserver

if ($xport==''tcp'') {

       $socket = stream_socket_server($address, $errno, $errstr);

}

elseif ($xport==''udp'') {

       $socket = stream_socket_server($address, $errno, $errstr, STREAM_SERVER_BIND);

}

if (!$socket) {

       echo "{$errstr} ({$errno}) ";

}

else {

       echo "listening {$xport}:{$port} ... ";

       if ($xport==''tcp'') {

              //许可一个socket连接,-1超时

              while ($conn = stream_socket_accept($socket,-1)) {

                     //得到访问的端口

                     $peer = stream_socket_get_name($conn,true);

                     echo "$peer ";

                  fwrite($conn, ''The local time is '' . date("Y-m-d H:i:s "));

                  fclose($conn);

              }

       }

       elseif ($xport==''udp'') {

              do {

                     //得到访问的端口

                  $pkt = stream_socket_recvfrom($socket, 1, 0, $peer);

                  echo "$peer ";

                  stream_socket_sendto($socket, date("Y-m-d H:i:s "), 0, $peer);

              } while ($pkt !== false);

       }

       //关闭socket

       fclose($socket);

}

?>

 

---------------------------- fsockopen(post)---------------------------

 

<?php

/**

 * @name test.php

 * @date Sat Jan 26 23:01:23 CST 2008

 * @copyright 马永占(MyZ)

 * @author 马永占(MyZ)

 * @link http://blog.111cn.net/mayongzhan/

 */

 

/**

 * php 发送POST请求

 *

 * @param string $url 提交到的地址

 * @param array $data 要提交的参数 array(''a''=>'''',''b''=>'''');

 * @return string

 */

function virtualPost($url, $data) {

       $url = parse_url($url);

       if (!$url) return "URL不能解析";

       if (!isset($url[''port'']))  $url[''port''] = "";

       if (!isset($url[''query''])) $url[''query''] = ""; 

       $encoded = "";

       while (list($k,$v) = each($data)) {

              $encoded .= ($encoded ? "&" : "");

              $encoded .= rawurlencode($k)."=".rawurlencode($v);

       }

       //$fp = stream_socket_client($url[''host''].":".($url[''port''] ? $url[''port''] : 80));

       $fp = fsockopen($url[''host''], $url[''port''] ? $url[''port''] : 80);

       if (!$fp) return "不能打开到$url[host]的连接";

       //发送

       fputs($fp, sprintf("POST %s%s%s HTTP/1.0 ", $url[''path''], $url[''query''] ? "?" : "", $url[''query'']));

       fputs($fp, "Host: $url[host] ");

       fputs($fp, "Content-type: application/x-www-form-urlencoded ");

       fputs($fp, "Content-length: " . strlen($encoded) . " ");

       fputs($fp, "Connection: close ");

       fputs($fp, "$encoded ");

       //接受

       $line = fgets($fp,1024);

       if (!eregi("^HTTP/1.. 200", $line)) return "返回结果错误";

       //滤掉空行

       $results = "";

       $inheader = 1;

       while(!feof($fp)) {

              $line = fgets($fp,1024);

              //把剩余的头信息过滤掉

              if ($inheader && ($line == " " || $line == " ")) {

                     $inheader = 0;

              }elseif (!$inheader) {

                     $results .= $line;

              }

       }

       fclose($fp);

       return $results;

}

echo virtualPost(''http://127.0.0.1/test/test2.php'',array(myz=>''马永占''));

 

?>

一、问题起源

稍大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的二级域名,而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个模块中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在这个服务器登录之后,进入另一个服务器的别的模块时,仍然需要重新登录,这就是一次登录,全部通行的问题,映射到技术上,其实就是各个服务器之间如何实现共享 SESSION 数据的问题。

二、PHP SESSION 的工作原理

在解决问题之前,先来了解一下 PHP SESSION 的工作原理。在客户端(如浏览器)登录网站时,被访问的 PHP 页面可以使用 session_start() 打开 SESSION,这样就会产生客户端的唯一标识 SESSION ID(此 ID 可通过函数 session_id() 获取/设置)。SESSION ID 可以通过两种方式保留在客户端,使得请求不同的页面时,PHP 程序可以获知客户端的 SESSION ID;一种是将 SESSION ID 自动加入到 GET 的 URL 中,或者 POST 的表单中,默认情况下,变量名为 PHPSESSID;另一种是通过 COOKIE,将 SESSION ID 保存在 COOKIE 中,默认情况下,这个 COOKIE 的名字为 PHPSESSID。这里我们主要以 COOKIE 方式进行说明,因为应用比较广泛。

那么 SESSION 的数据保存在哪里呢?当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中。默认情况下,php.ini 中设置的 SESSION 保存方式是 files(session.save_handler = files),即使用读写文件的方式保存 SESSION 数据,而 SESSION 文件保存的目录由 session.save_path 指定,文件名以 sess_ 为前缀,后跟 SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION 数据了。如果访问量大,可能产生的 SESSION 文件会比较多,这时可以设置分级目录进行 SESSION 文件的保存,效率会提高很多,设置方法为:session.save_path="N;/save_path",N 为分级的级数,save_path 为开始目录。当写入 SESSION 数据的时候,PHP 会获取到客户端的 SESSION_ID,然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件,不存在则创建之,最后将数据序列化之后写入文件。读取 SESSION 数据是也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的 SESSION 变量。

三、多服务器共享 SESSION 的主要障碍及解决办法

通过了解 SESSION 的工作原理,我们可以发现,在默认情况下,各个服务器会各自分别对同一个客户端产生 SESSION ID,如对于同一个用户浏览器,A 服务器产生的 SESSION ID 是 30de1e9de3192ba6ce2992d27a1b6a0a,而 B 服务器生成的则是 c72665af28a8b14c0fe11afe3b59b51b。另外,PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。




在PHP开发中对比起Cookie,Session 是存储在服务器端的会话,相对安全,并且不像 Cookie 那样有存储长度限制,本文简单介绍 Session 的使用。

  由于 Session 是以文本文件形式存储在服务器端的,所以不怕客户端修改 Session 内容。实际上在服务器端的 Session 文件,PHP 自动修改 Session 文件的权限,只保留了系统读和写权限,而且不能通过 ftp 修改,所以安全得多。PHPChina 开源社区门户k%W%e2CY

   对于 Cookie 来说,假设我们要验证用户是否登陆,就必须在 Cookie 中保存用户名和密码(可能是 md5 加密后字符串),并在每次请求页面的时候进行验证。如果用户名和密码存储在数据库,每次都要执行一次数据库查询,给数据库造成多余的负担。因为我们并不能 只做一次验证。为什么呢?因为客户端 Cookie 中的信息是有可能被修改的。假如你存储 $admin 变量来表示用户是否登陆,$admin 为 true 的时候表示登陆,为 false 的时候表示未登录,在第一次通过验证后将 $admin 等于 true 存储在 Cookie,下次就不用验证了,这样对么?错了,假如有人伪造一个值为 true 的 $admin 变量那不是就立即取的了管理权限么?非常的不安全。

   而 Session 就不同了,Session 是存储在服务器端的,远程用户没办法修改 Session 文件的内容,因此我们可以单纯存储一个 $admin 变量来判断是否登陆,首次验证通过后设置 $admin 值为 true,以后判断该值是否为 true,假如不是,转入登陆界面,这样就可以减少很多数据库操作了。而且可以减少每次为了验证 Cookie 而传递密码的不安全性了(Session 验证只需要传递一次,假如你没有使用 SSL 安全协议的话)。即使密码进行了 md5 加密,也是很容易被截获的。

  当然使用 Session 还有很多优点,比如控制容易,可以按照用户自定义存储等(存储于数据库)。我这里就不多说了。

  Session 在 php.ini 是否需要设置呢?一般不需要的,因为并不是每个人都有修改 php.ini 的权限,默认 Session 的存放路径是服务器的系统临时文件夹,我们可以自定义存放在自己的文件夹里,这个稍后我会介绍。

  开始介绍如何创建 Session。非常简单,真的。

  启动 Session 会话,并创建一个 $admin 变量:

<?php
// 启动 Session
session_start();
// 声明一个名为 admin 的变量,并赋空值。
$_SESSION["admin"] = null;
?>

  如果你使用了 Seesion,或者该 PHP 文件要调用 Session 变量,那么就必须在调用 Session 之前启动它,使用 session_start() 函数。其它都不需要你设置了,PHP 自动完成 Session 文件的创建。

  执行完这个程序后,我们可以到系统临时文件夹找到这个 Session 文件,一般文件名形如:sess_4c83638b3b0dbf65583181c2f89168ec,后面是 32 位编码后的随机字符串。用编辑器打开它,看一下它的内容:

  admin|N;

  一般该内容是这样的结构:

  变量名|类型:长度:值;

  并用分号隔开每个变量。有些是可以省略的,比如长度和类型。

  我们来看一下验证程序,假设数据库存储的是用户名和 md5 加密后的密码:

<?php

// 表单提交后...
$posts = $_POST;
// 清除一些空白符号
foreach ($posts as $key => $value)
{
$posts[$key] = trim($value);
}
$password = md5($posts["password"]);
$username = $posts["username"];

$query = "SELECT `username` FROM `user` WHERE `password` = ''$password''";
// 取得查询结果
$userInfo = $DB->getRow($query);

if (!empty($userInfo))
{
if ($userInfo["username"] == $username)
{
// 当验证通过后,启动 Session
session_start();
// 注册登陆成功的 admin 变量
[!--infotagslink--]

相关文章

  • 图解PHP使用Zend Guard 6.0加密方法教程

    有时为了网站安全和版权问题,会对自己写的php源码进行加密,在php加密技术上最常用的是zend公司的zend guard 加密软件,现在我们来图文讲解一下。 下面就简单说说如何...2016-11-25
  • ps怎么使用HSL面板

    ps软件是现在很多人都会使用到的,HSL面板在ps软件中又有着非常独特的作用。这次文章就给大家介绍下ps怎么使用HSL面板,还不知道使用方法的下面一起来看看。 &#8195;...2017-07-06
  • Plesk控制面板新手使用手册总结

    许多的朋友对于Plesk控制面板应用不是非常的了解特别是英文版的Plesk控制面板,在这里小编整理了一些关于Plesk控制面板常用的使用方案整理,具体如下。 本文基于Linu...2016-10-10
  • 使用insertAfter()方法在现有元素后添加一个新元素

    复制代码 代码如下: //在现有元素后添加一个新元素 function insertAfter(newElement, targetElement){ var parent = targetElement.parentNode; if (parent.lastChild == targetElement){ parent.appendChild(newEl...2014-05-31
  • 使用GruntJS构建Web程序之构建篇

    大概有如下步骤 新建项目Bejs 新建文件package.json 新建文件Gruntfile.js 命令行执行grunt任务 一、新建项目Bejs源码放在src下,该目录有两个js文件,selector.js和ajax.js。编译后代码放在dest,这个grunt会...2014-06-07
  • 使用percona-toolkit操作MySQL的实用命令小结

    1.pt-archiver 功能介绍: 将mysql数据库中表的记录归档到另外一个表或者文件 用法介绍: pt-archiver [OPTION...] --source DSN --where WHERE 这个工具只是归档旧的数据,不会对线上数据的OLTP查询造成太大影响,你可以将...2015-11-24
  • 如何使用php脚本给html中引用的js和css路径打上版本号

    在搜索引擎中搜索关键字.htaccess 缓存,你可以搜索到很多关于设置网站文件缓存的教程,通过设置可以将css、js等不太经常更新的文件缓存在浏览器端,这样访客每次访问你的网站的时候,浏览器就可以从浏览器的缓存中获取css、...2015-11-24
  • jQuery 1.9使用$.support替代$.browser的使用方法

    jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version , 取而代之的是 $.support 。 在更新的 2.0 版本中,将不再支持 IE 6/7/8。 以后,如果用户需要支持 IE 6/7/8,只能使用 jQuery 1.9。 如果要全面支持 IE,并混合...2014-05-31
  • MySQL日志分析软件mysqlsla的安装和使用教程

    一、下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz--19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gzResolving hackmysql.com... 64.13.232.157Conn...2015-11-24
  • 安装和使用percona-toolkit来辅助操作MySQL的基本教程

    一、percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检查master和slave数据的一致性 有效地对记录进行归档 查找重复的索...2015-11-24
  • C#注释的一些使用方法浅谈

    C#注释的一些使用方法浅谈,需要的朋友可以参考一下...2020-06-25
  • php语言中使用json的技巧及json的实现代码详解

    目前,JSON已经成为最流行的数据交换格式之一,各大网站的API几乎都支持它。我写过一篇《数据类型和JSON格式》,探讨它的设计思想。今天,我想总结一下PHP语言对它的支持,这是开发互联网应用程序(特别是编写API)必须了解的知识...2015-10-30
  • PHP实现无限级分类(不使用递归)

    无限级分类在开发中经常使用,例如:部门结构、文章分类。无限级分类的难点在于“输出”和“查询”,例如 将文章分类输出为<ul>列表形式; 查找分类A下面所有分类包含的文章。1.实现原理 几种常见的实现方法,各有利弊。其中...2015-10-23
  • php类的使用实例教程

    php类的使用实例教程 <?php /** * Class program for yinghua05-2 * designer :songsong */ class Template { var $tpl_vars; var $tpl_path; var $_deb...2016-11-25
  • 双冒号 ::在PHP中的使用情况

    前几天在百度知道里面看到有人问PHP中双冒号::的用法,当时给他的回答比较简洁因为手机打字不大方便!今天突然想起来,所以在这里总结一下我遇到的双冒号::在PHP中使用的情况!双冒号操作符即作用域限定操作符Scope Resoluti...2015-11-08
  • 浅析Promise的介绍及基本用法

    Promise是异步编程的一种解决方案,在ES6中Promise被列为了正式规范,统一了用法,原生提供了Promise对象。接下来通过本文给大家介绍Promise的介绍及基本用法,感兴趣的朋友一起看看吧...2021-10-21
  • 使用jquery修改表单的提交地址基本思路

    基本思路: 通过使用jquery选择器得到对应表单的jquery对象,然后使用attr方法修改对应的action 示例程序一: 默认情况下,该表单会提交到page_one.html 点击button之后,表单的提交地址就会修改为page_two.html 复制...2014-06-07
  • PHP mysql与mysqli事务使用说明 分享

    mysqli封装了诸如事务等一些高级操作,同时封装了DB操作过程中的很多可用的方法。应用比较多的地方是 mysqli的事务。...2013-10-02
  • Postman安装与使用详细教程 附postman离线安装包

    这篇文章主要介绍了Postman安装与使用详细教程 附postman离线安装包,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-05
  • vs2019安装和使用详细图文教程

    这篇文章主要介绍了vs2019安装和使用详细图文教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-25