Discussion:
WSDL and "extends"
aouriques
2007-12-21 15:24:23 UTC
Permalink
Hello,

I would like to know how can I use the "extends" for services.
I have a Customer service that extends the User service.

/**
....
* @service
* @binding.soap
* @location http://mydomain.com/SOA/Customer.php
*/
class Customer extends User {
...
}

What should I add into the comments or what should I to do when using
an extension?
When I use the Customer alone it works fine, but when I use the
Customer with the extension the WSDL is not generated.

Thank you!
Graham Charters
2008-01-02 17:07:48 UTC
Permalink
Hi,

Sorry for not getting back to you sooner. Extends is not something
I'm aware of being supported. The SCA_AnnotationReader uses
get_class_methods to return the methods which the class may expose
(depends on whether they're public or are restricted using an
interface). I haven't tried it yet, but my guess is this doesn't
return methods defined by the parent class. If this is the case, then
this code would need updating to include parent classes when
determining the candidate methods to be exposed.

I hope this helps.

Graham.
Post by aouriques
Hello,
I would like to know how can I use the "extends" for services.
I have a Customer service that extends the User service.
/**
....
*/
class Customer extends User {
...
}
What should I add into the comments or what should I to do when using
an extension?
When I use the Customer alone it works fine, but when I use the
Customer with the extension the WSDL is not generated.
Thank you!
Graham Charters
2008-01-02 17:18:38 UTC
Permalink
OK, so I should have tried it before responding....

Get_class_methods does include methods from parent classes. I've just
tried the following example:

filename: DerivedClass.php

<?php

include 'SCA/SCA.php';

class ParentClass {

public function method1() {}
}

/**
* My service using extension
*
* @service
* @binding.soap
*/
class DerivedClass extends ParentClass {

public function method2() {}
}

?>

When I point my browser at http://...../DerivedClass.php?wsdl, it
returns the following, which includes both methods.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns2="http://DerivedClass" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/
soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://DerivedClass">
<types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://DerivedClass"
elementFormDefault="qualified">
<xs:element name="method2">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="method2Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1">
<xs:complexType>
<xs:sequence>

</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>

</xs:schema>
</types>

<wsdl:message name="method2Request">
<wsdl:part name="method2Request" element="tns2:method2"/>
</wsdl:message>
<wsdl:message name="method2Response">
<wsdl:part name="return" element="tns2:method2Response"/>
</wsdl:message>

<wsdl:message name="method1Request">
<wsdl:part name="method1Request" element="tns2:method1"/>
</wsdl:message>
<wsdl:message name="method1Response">
<wsdl:part name="return" element="tns2:method1Response"/>
</wsdl:message>
<wsdl:portType name="DerivedClassPortType">
<wsdl:operation name="method2">
<wsdl:input message="tns2:method2Request"/>

<wsdl:output message="tns2:method2Response"/>
</wsdl:operation>
<wsdl:operation name="method1">
<wsdl:input message="tns2:method1Request"/>
<wsdl:output message="tns2:method1Response"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DerivedClassBinding"
type="tns2:DerivedClassPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>

<wsdl:operation name="method2">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>

<wsdl:operation name="method1">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>

</wsdl:binding>
<wsdl:service name="DerivedClassService">
<wsdl:port name="DerivedClassPort"
binding="tns2:DerivedClassBinding">
<soap:address location="http://localhost/bugs/extends/
DerivedClass.php"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

<!-- this line identifies this file as WSDL generated by SCA for PHP.
Do not remove -->

Can you give this example a try and see what happens?

Regards,

Graham.
Post by Graham Charters
Hi,
Sorry for not getting back to you sooner. Extends is not something
I'm aware of being supported. The SCA_AnnotationReader uses
get_class_methods to return the methods which the class may expose
(depends on whether they're public or are restricted using an
interface). I haven't tried it yet, but my guess is this doesn't
return methods defined by the parent class. If this is the case, then
this code would need updating to include parent classes when
determining the candidate methods to be exposed.
I hope this helps.
Graham.
Post by aouriques
Hello,
I would like to know how can I use the "extends" for services.
I have a Customer service that extends the User service.
/**
....
*/
class Customer extends User {
...
}
What should I add into the comments or what should I to do when using
an extension?
When I use the Customer alone it works fine, but when I use the
Customer with the extension the WSDL is not generated.
Thank you!
aouriques
2008-01-02 17:46:00 UTC
Permalink
First of all, thank you Graham.

I have tested your example and it works fine, but I am trying to
create another structure where I have a parent class in a separated
file.
For example:
<?php
include_once 'SCA/SCA.php';

/**
* My service using extension
*
* @service
* @binding.soap
*/
class ParentClass {

public function method1() {}

}

?>

<?php
include_once 'ParentClass.php';
include_once 'SCA/SCA.php';

/**
* My service using extension
*
* @service
* @binding.soap
*/
class DerivedClass extends ParentClass {

public function method2() {}

}

?>

Using this files structure it doesn't work.

Thank you.
Post by Graham Charters
OK, so I should have tried it before responding....
Get_class_methods does include methods from parent classes. I've just
filename: DerivedClass.php
<?php
include 'SCA/SCA.php';
class ParentClass {
public function method1() {}
}
/**
* My service using extension
*
*/
class DerivedClass extends ParentClass {
public function method2() {}
}
?>
When I point my browser athttp://...../DerivedClass.php?wsdl, it
returns the following, which includes both methods.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns2="http://DerivedClass" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/
soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://DerivedClass">
<types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://DerivedClass"
elementFormDefault="qualified">
<xs:element name="method2">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method2Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</types>
<wsdl:message name="method2Request">
<wsdl:part name="method2Request" element="tns2:method2"/>
</wsdl:message>
<wsdl:message name="method2Response">
<wsdl:part name="return" element="tns2:method2Response"/>
</wsdl:message>
<wsdl:message name="method1Request">
<wsdl:part name="method1Request" element="tns2:method1"/>
</wsdl:message>
<wsdl:message name="method1Response">
<wsdl:part name="return" element="tns2:method1Response"/>
</wsdl:message>
<wsdl:portType name="DerivedClassPortType">
<wsdl:operation name="method2">
<wsdl:input message="tns2:method2Request"/>
<wsdl:output message="tns2:method2Response"/>
</wsdl:operation>
<wsdl:operation name="method1">
<wsdl:input message="tns2:method1Request"/>
<wsdl:output message="tns2:method1Response"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DerivedClassBinding"
type="tns2:DerivedClassPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<wsdl:operation name="method2">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="method1">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DerivedClassService">
<wsdl:port name="DerivedClassPort"
binding="tns2:DerivedClassBinding">
<soap:address location="http://localhost/bugs/extends/
DerivedClass.php"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<!-- this line identifies this file as WSDL generated by SCA for PHP.
Do not remove -->
Can you give this example a try and see what happens?
Regards,
Graham.
Post by Graham Charters
Hi,
Sorry for not getting back to you sooner. Extends is not something
I'm aware of being supported. The SCA_AnnotationReader uses
get_class_methods to return the methods which the class may expose
(depends on whether they're public or are restricted using an
interface). I haven't tried it yet, but my guess is this doesn't
return methods defined by the parent class. If this is the case, then
this code would need updating to include parent classes when
determining the candidate methods to be exposed.
I hope this helps.
Graham.
Post by aouriques
Hello,
I would like to know how can I use the "extends" for services.
I have a Customer service that extends the User service.
/**
....
*/
class Customer extends User {
...
}
What should I add into the comments or what should I to do when using
an extension?
When I use the Customer alone it works fine, but when I use the
Customer with the extension the WSDL is not generated.
Thank you!
Graham Charters
2008-01-02 21:37:45 UTC
Permalink
Hi,

What you're seeing is a consequence of the php internals design, in
that a derived class is not processed at compile-time. I encountered
this when adding the ability to control service methods through an
interface. You can get round the problem by moving the include for
SCA.php to after the definition of the derived class (I think this
should be the recommended practice, and needs updating in the docs).
The following works for me:

ParentClass.php

<?php

class ParentClass {

public function method1() {}
}

?>

DerivedClass.php

<?php

include 'ParentClass.php';

/**
* My service using extension
*
* @service
* @binding.soap
*/
class DerivedClass extends ParentClass {

public function method2() {}
}

include 'SCA/SCA.php';

?>

I hope this helps.

Graham.
Post by aouriques
First of all, thank you Graham.
I have tested your example and it works fine, but I am trying to
create another structure where I have a parent class in a separated
file.
<?php
include_once 'SCA/SCA.php';
/**
* My service using extension
*
*/
class ParentClass {
public function method1() {}
}
?>
<?php
include_once 'ParentClass.php';
include_once 'SCA/SCA.php';
/**
* My service using extension
*
*/
class DerivedClass extends ParentClass {
public function method2() {}
}
?>
Using this files structure it doesn't work.
Thank you.
Post by Graham Charters
Get_class_methods does include methods from parent classes. I've just
filename: DerivedClass.php
<?php
include 'SCA/SCA.php';
class ParentClass {
public function method1() {}
}
/**
* My service using extension
*
*/
class DerivedClass extends ParentClass {
public function method2() {}
}
?>
When I point my browser athttp://...../DerivedClass.php?wsdl, it
returns the following, which includes both methods.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:tns2="http://DerivedClass" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/
soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://DerivedClass">
<types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://DerivedClass"
elementFormDefault="qualified">
<xs:element name="method2">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method2Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="method1Response">
<xs:complexType>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</types>
<wsdl:message name="method2Request">
<wsdl:part name="method2Request" element="tns2:method2"/>
</wsdl:message>
<wsdl:message name="method2Response">
<wsdl:part name="return" element="tns2:method2Response"/>
</wsdl:message>
<wsdl:message name="method1Request">
<wsdl:part name="method1Request" element="tns2:method1"/>
</wsdl:message>
<wsdl:message name="method1Response">
<wsdl:part name="return" element="tns2:method1Response"/>
</wsdl:message>
<wsdl:portType name="DerivedClassPortType">
<wsdl:operation name="method2">
<wsdl:input message="tns2:method2Request"/>
<wsdl:output message="tns2:method2Response"/>
</wsdl:operation>
<wsdl:operation name="method1">
<wsdl:input message="tns2:method1Request"/>
<wsdl:output message="tns2:method1Response"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DerivedClassBinding"
type="tns2:DerivedClassPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
<wsdl:operation name="method2">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="method1">
<soap:operation soapAction=""/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DerivedClassService">
<wsdl:port name="DerivedClassPort"
binding="tns2:DerivedClassBinding">
<soap:address location="http://localhost/bugs/extends/
DerivedClass.php"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
<!-- this line identifies this file as WSDL generated by SCA for PHP.
Do not remove -->
Can you give this example a try and see what happens?
Regards,
Graham.
Post by Graham Charters
Hi,
Sorry for not getting back to you sooner. Extends is not something
I'm aware of being supported. The SCA_AnnotationReader uses
get_class_methods to return the methods which the class may expose
(depends on whether they're public or are restricted using an
interface). I haven't tried it yet, but my guess is this doesn't
return methods defined by the parent class. If this is the case, then
this code would need updating to include parent classes when
determining the candidate methods to be exposed.
I hope this helps.
Graham.
Post by aouriques
Hello,
I would like to know how can I use the "extends" for services.
I have a Customer service that extends the User service.
/**
....
*/
class Customer extends User {
...
}
What should I add into the comments or what should I to do when using
an extension?
When I use the Customer alone it works fine, but when I use the
Customer with the extension the WSDL is not generated.
Thank you!
Loading...