비누를 사용한 상태의 PHP 웹 서비스
-
08-07-2019 - |
문제
SOAP 확장을 사용하여 PHP에서 상태 가득한 웹 서비스를 구현하려고합니다. (예, 웹 서비스가 무국적이어야한다는 것을 알고 있습니다. 실제로 지속하려는 것은 세션 ID의 형태이므로 서비스에 대한 모든 호출마다 인증 할 필요가 없습니다). PHP.NET의 API 문서는 이것에 대해 다소 부족하며 그에 대한 다른 것이 많지 않습니다.
나는 그것을 논의하는 한 페이지를 찾았다 (http://bytes.com/forum/thread160816.html) 및 테스트로 코드를 구현했습니다. 웹 서비스를 소비하고 각 기능을 호출하고 결과를 표시하는 작은 .NET 응용 프로그램을 구축했습니다. 내가 읽은 내용에서 PHP SOAP 확장은 setClass () 함수를 사용하여 클래스에서 함수가 캡슐화되고 setPersistence () 함수가 soap_persistence_session으로 전달되는 한 호출 사이에 클래스 변수를 지속합니다.
내 코드는 다음과 같습니다.
<?php
class User
{
var $name = "Initial value";
function setName($name)
{
$this->name = $name;
// Tried this too.
// $this->name = "Set to string constant" ;
}
function getName()
{
// This always returns "Initial value"
return $this->name;
}
}
// Tried placing session_start() in several places
// before $server->handle()...
// One guy says this doesn't need to be called.
// I assume it depends on if session autostart is on.
session_start();
$server = new SoapServer(null, array('uri' => 'http://localhost/'));
$server->setClass('User');
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();
?>
내가 겪는 문제는 $ 이름이 통화 사이에 지속되지 않는다는 것입니다. 나는 항상 setName ()에 할당 할 수있는 값이 아니라 항상 초기화 된 값을 얻습니다. 내가 언급했듯이, 나는 데이터베이스에 대해 인증 한 후 세션 ID를 지속하려고 노력하고 있습니다. 누군가 더 나은 방법이 있다면 나는 제안에 열려 있습니다. 그러나 나는 여전히 일반적인 사례를 해결하고 싶습니다. 누구든지 아이디어가 있습니까?
해결책
나는 실제로 내 자신의 문제를 해결했다.
나는 다음과 같은 가정하에 일하고 있었다. 1) .net은 쿠키를 자동으로 처리한다. 그리고 2) 나의 문제는 PHP에 관한 것이었다. 그 경우도 그렇지 않았습니다. 내 PHP 코드는 괜찮 았지만 세션 쿠키를 처리하기 위해 .NET 코드에 요소 하나를 추가해야했습니다.
웹 서비스 객체를 인스턴스화 한 후 CookieContainer 클래스의 인스턴스를 웹 서비스 객체에 할당해야했습니다. 최종 클라이언트 측 코드는 다음과 같습니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WsTest
{
public partial class PhpWsForm : Form
{
private localhost.MyWebService ws;
public PhpWsForm()
{
InitializeComponent();
ws = new WsTest.localhost.MyWebService();
// The line below is the part that I forgot!
ws.CookieContainer = new System.Net.CookieContainer();
}
private void butSetVal_Click(object sender, EventArgs e)
{
ws.setName(txtSetVal.Text);
}
private void butGetVal_Click(object sender, EventArgs e)
{
txtGetVal.Text = ws.getName();
}
}
}
어쨌든 감사합니다!
다른 팁
대부분의 비누 클라이언트는 각 요청마다 새로운 연결을 시작하므로 "세션"이 없습니다.
SOAP 서비스가 서비스 인 경우 모든 회신에서 SOAP 봉투의 어딘가에 세션 ID를 보내고 모든 후속 요청에서 세션 ID를 전달하도록 클라이언트에게 요청할 수 있습니다.
고객이 이제 Beaviour에 대한 단서와 통제력을 가지고 있기 때문에 이것은 훨씬 좋습니다.
Stateful Web Service를 소비하려면 클라이언트 측의 SOAP 쿠키에서 서버 세션의 세션 ID를 설정해야합니다. SOAP 요청이 전송 될 때마다 기본적으로 서버는 고유 세션 ID를 생성합니다. 이를 방금 설정하지 않기 위해 SOAP 쿠키에서 첫 번째 요청에서 얻은 세션 ID가 발생했습니다. 그 쿠키는 모든 후속 비누 호출과 함께 보내집니다. 예를 들어 SOAP를 사용하여 ASP.NET 웹 서비스를 소비하는 경우 첫 번째 WS 호출 후 다음과 같은 응답 헤더를 얻습니다.
$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
$headers = $client->__getLastResponseHeaders();
지금 $headers
'asp.net_sessionid'와 같은 이름의 세션 ID를 포함해야합니다. ID를 얻으십시오 $headers
다음과 같이 쿠키를 만듭니다.
//$client->__setCookie($cookieName, $cookieValue);
$client->__setCookie('ASP.NET_SessionId', $cookieValue);
이제 클라이언트의 모든 SOAP 요청에는이 세션 ID가 포함되어 있으며 귀하의 주는 서버에서 지속됩니다.