Bug #51561 [Com]: SoapServer with a extented class and using sessions, lost the setPersistence()
| From: | nielsdos@php.net | Date: | Fri, 13 Oct 2023 23:44:58 +0000 |
| Subject: | Bug #51561 [Com]: SoapServer with a extented class and using sessions, lost the setPersistence() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-245563@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=51561&edit=1
ID: 51561
Comment by: nielsdos@php.net
Reported by: marciomaianunes at hotmail dot com
Summary: SoapServer with a extented class and using sessions,
lost the setPersistence()
Status: Open
Type: Bug
Package: SOAP related
Operating System: Linux 2.6.26
PHP Version: 5.2.11
Block user comment: N
Private report: N
New Comment:
I found the root cause.
When using persistent sessions, the soap server object is put into the session storage.
On the next request, session_start() at the beginning will decode the session object, before the
require_once has executed. So that means the soap server object will be decoded before its parent
(Server2) has been compiled. This causes the server object to be updated in the session storage to
be of class entry PHP_COMPLETE_CLASS. The consequence of this is that the check:
Z_OBJCE_P(tmp_soap_p) == service->soap_class.ce) will fail, causing the session not
to work.
I see two options to fix this:
- Delay deserialization by storing the object as a string. Proof of concept implementation that
works here: https://github.com/nielsdos/php-src/pull/52
- Live with this limitation that the session must not be started before the classes are loaded, and
emit a warning to the user. I looked into this but the warning is thrown away by the handle()
method.
Previous Comments:
------------------------------------------------------------------------
[2010-04-15 12:55:27] marciomaianunes at hotmail dot com
Same error in PHP 5.2.6-1+lenny3
------------------------------------------------------------------------
[2010-04-15 12:50:56] marciomaianunes at hotmail dot com
Description:
------------
A SoapServer using sessions and extending some class included by require or
include functions, lose the persistence seted by setPersistence
(SOAP_PERSISTENCE_SESSION)
The script below will work fine with one of 3 changes (no idea why):
- Declaring the class "Server2" in the same file as class "Server" (Server1.php)
and removing the require_once(Server2.php);
- Removing the "session_start();" from server.php
- If class "Server" do no extend any class, it also works.
Thanks a lot!
Test script:
---------------
## Client.php ##
<?php
$cli = new SoapClient(null, array('location' => "http://localhost:81/bugTest/Server.php",
'uri' => "blablabla.com",'encoding' =>
"ISO-8859-1",'soap_version' => SOAP_1_2));
$cli->setValue(100);
$response = $cli->getValue();
echo "Get = ".$response;
?>
## Server.php ##
<?php
session_start();
require_once("Server2.php");
class Server extends Server2 {
private $value;
public function setValue($param) { $this->value = $param; }
public function getValue() { return $this->value; }
}
$server = new SoapServer(null, array('uri' =>
"blablabla.com",'encoding' => "ISO-8859-1",'soap_version'
=> SOAP_1_2));
$server->setClass("Server");
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();
?>
## Server2.php ##
<?php class Server2{ private $nothing; } ?>
Expected result:
----------------
Get = 100
Actual result:
--------------
Get =
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=51561&edit=1