Hi,

I am gone crosseyed from trying to figure this out. I dont ususally post on this site I am half scared of getting told off for being out of my league!!!

I am creating a website for a training company and I need to get the course info from their Client Services System using SOAP request and response. For client confidentiality I can not put the wsdl file up. I have been testing how to do this by following this tutorial and using this as an example http://www.webservicex.net/stockquote.asmx?WSDL

I can not create the same results as in that tut my results are coming back as a string rather than an array? Any help or advice would be amazing. This is my code:

<?php

        $wsdl = "http://www.webservicex.net/stockquote.asmx?WSDL";    
        $client = new SoapClient($wsdl);
        $stock = "bmi";    
        $parameters= array("symbol"=>$stock);    
        $values = $client->GetQuote($parameters);

    $xml = $values->GetQuoteResult;

    print "<pre>\n";
        print_r($xml);
        print "</pre>";

    ?>

and this is the output I am getting

BMI58.402/27/20154:01pm+0.0958.4058.8358.1134145836.2M58.31+0.15%46.47 - 61.352.0628.31Badger Meter

I think if I can manage this basic task I can work it around my clients request.
Hope I have given enough info, and thanks in advance I do appreciate any time given to help :)

Recommended Answers

All 14 Replies

Remove the <pre> and out the result. It should be XML. Pre formatting is hiding that from you.

The reason you're not seeing an array, is because the response is a string of XML data.

From the XML file:
<s:element minOccurs="0" maxOccurs="1" name="GetQuoteResult" type="s:string"/>

What you can do is parse the xml data with simplexml to help create an array.

<?php

    $wsdl = "http://www.webservicex.net/stockquote.asmx?WSDL"; 

    $client = new SoapClient($wsdl);

    $stock = "bmi";

    $parameters= array("symbol"=>$stock);

    $values = $client->GetQuote($parameters);

    $xml = simplexml_load_string($values->GetQuoteResult);

    $json = json_encode($xml);

    $array = json_decode($json,TRUE);

    print "<pre>\n";
    print_r($array['Stock']);
    print "</pre>";

?>

btw, most/none (and myself) of the regular members on this site are ever going to tell you that you're out of your league. We may suggest learning resources to digest before taking on something complicated, but I would never discourage learning/using PHP ;-)

Also, I prefer var_dump usually over print_r when debugging. If you were using var_dump, it would have shown you the xml rather than the text string.

Thanks hericles and pixelsoul, that was a huge help.

I applied the same to my Courses case and did a var_dump,

var_dump($xml)i get bool(false)

var_dump($values) i get....
object(stdClass)#1 (1) { ["getCourseInfoResult"]=> object(stdClass)#6 (1) { ["any"]=> string(56666) "......and a big long string of what I want to be the array elements!!!"

I am starting to think maybe the wsdl file is flawed? Is it possible to PM the actual details to you?

You can PM the details if you would like. I am in Portland Oregon though, and it's 1:30am here, and I'm dead tired at this point :). If you want to wait for me to wake up, I can take a look then.

Oh sorry, Im in Ireland (9.30am!).
That'd be great no rush at all :)

Can anyone tell me why I am getting Null for this:

<?php
    $wsdl = "https://namedeleted/courseinfo/courseinfo.asmx?WSDL"; 
    $client = new SoapClient($wsdl);
    $ref = 64566;
    $parameters= array("reference"=>$ref);
    $values = $client->getCourseDetail($parameters);
    $xml = simplexml_load_string($values->getCourseDetailResult);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    print "<pre>\n";
    print_r($array['Course']);
    print "</pre>";

    var_dump($array);
?>

I need to get an array of the course details something like this. It is a multidimentional array.

Array(
                  [ReferenceNo] =>64566
                  [CourseID] => COQ69
                  [CourseName] => Course Name
                  [DeliveryMethod] => Evening Course                 
                  [StartDate] => 2015-04-13
                  [FinishDate] =>2015-04-24
                  [Duration] => 2 weeks
                  [Capacity] =>16
                  [CourseLocation] = > Location Details
                  [Modules] =>   **This an array within the array?**
)

Thanks in advacne for any time of help given :)

Hi!

Apparently you get NULL, but PHP is also sending a warning:

Warning: simplexml_load_string() expects parameter 1 to be string, object given

because $values->getCourseDetailResult is an object, and outputs:

stdClass Object
(
    [any] => XML is here ...
)

So change your previous:

$xml = simplexml_load_string($values->getCourseDetailResult);

To:

$xml = simplexml_load_string($values->getCourseDetailResult->any);

and it should work fine.

Thank you so much Cereal, that had my head spinning for the last week. I was just about to throw in the towel.

I am used to creating and working with objects in php, can I access the properties of this object in the same way?

Yes you can, SimpleXML is going to create an object of that string, so it should be easy, for example:

print_r($xml->Course);

Or to get a specific property:

echo $xml->Course->CourseName;

Cereal, you have made my life so much easier thank you so much :)

Hi again :)

My college have changed their web service, I am trying to apply same technique as above but getting bool(false). It ssuppsoed to be a more flexible service but I cant get a grip of it, any help appreciated.

    $wsdl = "http://service.fetchcourses.ie/service/FetchCourse.svc?wsdl"; 
    $client = new SoapClient($wsdl);
    $ref = "25";
    $parameters= array("ProviderId"=>$ref);
    $values = $client->SearchCourseReturnCourseId($parameters);
    $xml = simplexml_load_string($values->SearchCourseReturnCourseIdResult->any);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    print "<pre>\n";
    print_r($array['CourseIds']);
    print "</pre>";
    var_dump($xml);

This is the request in SoapUI

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:sol="http://schemas.datacontract.org/2004/07/Solas.FetchCourses.DataContract">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:SearchCourseReturnCourseId>
           <tem:criteria>
                <sol:ProviderId>25</sol:ProviderId>
         </tem:criteria>
      </tem:SearchCourseReturnCourseId>
   </soapenv:Body>
</soapenv:Envelope>

and it returns the following...

`

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <SearchCourseReturnCourseIdResponse xmlns="http://tempuri.org/">
         <SearchCourseReturnCourseIdResult xmlns:a="http://schemas.datacontract.org/2004/07/Solas.FetchCourses.DataContract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:ResponseInfo>
               <a:ResponseCode>0</a:ResponseCode>
               <a:ResponseMessage>Return CourseIds Successful</a:ResponseMessage>
               <a:ResponseStatus>Success</a:ResponseStatus>
            </a:ResponseInfo>
            <a:courses>
               <a:CourseIds>
                  <a:CourseId>1562</a:CourseId>
               </a:CourseIds>
               <a:CourseIds>
                  <a:CourseId>1604</a:CourseId>
               </a:CourseIds>
              ..........
            </a:courses>
         </SearchCourseReturnCourseIdResult>
      </SearchCourseReturnCourseIdResponse>
   </s:Body>
</s:Envelope>

`

Hi,

if you add echo $client->__getLastRequest(); you can see what is sent to the SOAP server, in this case it will not set the sol namespace, see:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"><SOAP-ENV:Body><ns1:SearchCourseReturnCourseId/></SOAP-ENV:Body></SOAP-ENV:Envelope>

Since it's a complex request, use an object, basically do this:

$search = new stdClass;
$search->criteria = new stdClass;
$search->criteria->ProviderId = 25;

Full example:

<?php

$wsdl   = "http://service.fetchcourses.ie/service/FetchCourse.svc?wsdl"; 
$client = new SoapClient($wsdl, ['trace' => TRUE]);

$search = new stdClass;
$search->criteria = new stdClass;
$search->criteria->ProviderId = 25;

$values = $client->SearchCourseReturnCourseId($search);

# get response message
print $values->SearchCourseReturnCourseIdResult->ResponseInfo->ResponseMessage;

# get first listed course
print $values->SearchCourseReturnCourseIdResult->courses->CourseIds[1]->CourseId;

For reference see:

Hi Cereal,

Thanks once again for taking the time to help. I can use that array of course ids to loop the GetIndividualCourseDetail request, I just need to get the below code working, and returning the data in xml format.

$wsdl   = "http://service.fetchcourses.ie/service/FetchCourse.svc?wsdl"; 
$client = new SoapClient($wsdl, ['trace' => TRUE]);
$search = new stdClass;
$search->criteria = new stdClass;
$search->criteria->CourseId = 12262;
$values = $client->GetIndividualCourseDetail($search);

# get response message
print $values->GetIndividualCourseDetailResult->ResponseInfo->ResponseMessage;

This is the request in SoapUI

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <tem:GetIndividualCourseDetail>
         <!--Optional:-->
         <tem:CourseId>12262</tem:CourseId>
     </tem:GetIndividualCourseDetail>
   </soapenv:Body>
</soapenv:Envelope>

and it should return teh following

s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <GetIndividualCourseDetailResponse xmlns="http://tempuri.org/">
         <GetIndividualCourseDetailResult xmlns:a="http://schemas.datacontract.org/2004/07/Solas.FetchCourses.DataContract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:AccessTransferAndProgression>Progress to working within industry or continue on to
complete major award in Security 4M1976</a:AccessTransferAndProgression>
            <a:CategoryDescription>Evening Training</a:CategoryDescription>
            <a:CentreName>ccccccccccccccccccccc</a:CentreName>
            <a:CertificationRequirements>Door 
Guarding Skills 4N1118
Communications 4N0689</a:CertificationRequirements>
            <a:CourseCapacity>20</a:CourseCapacity>
            <a:CourseCode>q8651</a:CourseCode>
            <a:CourseContactEmail>xxxx</a:CourseContactEmail>
            <a:CourseContactFirstName>Carol</a:CourseContactFirstName>
            <a:CourseContactLastName>xxxx</a:CourseContactLastName>
            <a:CourseContactPhone>xxxxx</a:CourseContactPhone>
            <a:CourseDescription>Description
On successful completion of the programme, learners may progress to further education and training.</a:CourseDescription>
            <a:CourseFee>200.0000</a:CourseFee>
            <a:CourseId>12262</a:CourseId>
            <a:CourseTitle>Door Security </a:CourseTitle>
            <a:DateActualFinish>2016-11-20T00:00:00</a:DateActualFinish>
            <a:DateActualStart>2016-09-06T00:00:00</a:DateActualStart>
            <a:DateClosing i:nil="true"></a:DateClosing>
            <a:DeliveryMode>Classroom</a:DeliveryMode>
            <a:DeliveryTime>Evening</a:DeliveryTime>
            <a:DeliveryType>Parttime</a:DeliveryType>
            <a:DurationDays>0</a:DurationDays>
            <a:DurationWeeks>11</a:DurationWeeks>
            <a:HoursPerWeek>08 Hrs 00 Mins</a:HoursPerWeek>
            <a:ISCEDDescription>Services</a:ISCEDDescription>
            <a:LearnerAge>Statutory School Leaving Age</a:LearnerAge>
            <a:LearnerAptitude>Good numerical skills and verbal and written command of the English language along with good communication skills are essential.</a:LearnerAptitude>
            <a:LearnerEducation>Applicants must have achieved a FETAC Level 3 Major Award or its equivalent.</a:LearnerEducation>
            <a:LearnerPreviousExperience>None required</a:LearnerPreviousExperience>
            <a:LearningOutcomes>DOutline the training location's safety guidelines, rules/regulations, and the course objectives and certification.
Demonstrate the skills and related knowledge required to perform door security duties. 
Demonstrate the skills and related knowledge required to perform security guarding duties. 
Plan and achieve realistic work goals.</a:LearningOutcomes>
            <a:Notes></a:Notes>
            <a:OnlineApplicationURL></a:OnlineApplicationURL>
            <a:RegistrationFee>0.0000</a:RegistrationFee>
            <a:TargetAwardAchievable>Yes</a:TargetAwardAchievable>
            <a:TargetAwardCode>4M19l;l;</a:TargetAwardCode>
            <a:TargetAwardTitle>Private Security Services</a:TargetAwardTitle>
            <a:TargetAwardingBodyName>QQI</a:TargetAwardingBodyName>
            <a:TutionType>Group</a:TutionType>
            <a:VenueAddress>ksalkslakslka</a:VenueAddress>
            <a:VenueEircode></a:VenueEircode>
            <a:VenueLocationLatitude>51.894089474023708</a:VenueLocationLatitude>
            <a:VenueLocationLongitude>-8.520176603859</a:VenueLocationLongitude>
            <a:VenueName> Training Centre</a:VenueName>
            <a:WorkPlacementDays i:nil="true"></a:WorkPlacementDays>
            <a:WorkPlacementWeeks i:nil="true"></a:WorkPlacementWeeks>
            <a:VenueFacilities>
               <a:VenueFacility>
                  <a:FacilityDescription>Free Parking</a:FacilityDescription>
               </a:VenueFacility>
               <a:VenueFacility>
                  <a:FacilityDescription>Wheel Chair Access</a:FacilityDescription>
               </a:VenueFacility>
               <a:VenueFacility>
                  <a:FacilityDescription>Tea/Coffee Making</a:FacilityDescription>
               </a:VenueFacility>
            </a:VenueFacilities>
            <a:PreRequisites></a:PreRequisites>
            <a:Modules>
               <a:Module>
                  <a:ModuleTitle>Door Security Procedures 4N1114</a:ModuleTitle>
                  <a:awards>
                     <a:Award>
                        <a:AwardCode>4N1114</a:AwardCode>
                        <a:AwardTitle>Door Security Procedures</a:AwardTitle>
                        <a:AwardingBody>QQI</a:AwardingBody>
                     </a:Award>
                  </a:awards>
               </a:Module>
               <a:Module>
                  <a:ModuleTitle>Induction To Course</a:ModuleTitle>
                  <a:awards>
                     <a:Award>
                        <a:AwardCode i:nil="true"></a:AwardCode>
                        <a:AwardTitle i:nil="true"></a:AwardTitle>
                        <a:AwardingBody i:nil="true"></a:AwardingBody>
                     </a:Award>
                  </a:awards>
               </a:Module>
               <a:Module>
                  <a:ModuleTitle>Communications (4N0689)</a:ModuleTitle>
                  <a:awards>
                     <a:Award>
                        <a:AwardCode>4N0689</a:AwardCode>
                        <a:AwardTitle>Communications</a:AwardTitle>
                        <a:AwardingBody>QQI</a:AwardingBody>
                     </a:Award>
                  </a:awards>
               </a:Module>
               <a:Module>
                  <a:ModuleTitle>Guarding Skills 4N1118</a:ModuleTitle>
                  <a:awards>
                     <a:Award>
                        <a:AwardCode>4N1118</a:AwardCode>
                        <a:AwardTitle>Guarding Skills</a:AwardTitle>
                        <a:AwardingBody>QQI</a:AwardingBody>
                     </a:Award>
                  </a:awards>
               </a:Module>
            </a:Modules>
            <a:Timetable>
               <a:Timetable>
                  <a:Afternoon>false</a:Afternoon>
                  <a:DOW>2</a:DOW>
                  <a:Evening>true</a:Evening>
                  <a:Morning>false</a:Morning>
               </a:Timetable>
               <a:Timetable>
                  <a:Afternoon>false</a:Afternoon>
                  <a:DOW>4</a:DOW>
                  <a:Evening>true</a:Evening>
                  <a:Morning>false</a:Morning>
               </a:Timetable>
            </a:Timetable>
            <a:ResponseInfo>
               <a:ResponseCode>0</a:ResponseCode>
               <a:ResponseMessage>Get Course Detail Successful</a:ResponseMessage>
               <a:ResponseStatus>Success</a:ResponseStatus>
            </a:ResponseInfo>
         </GetIndividualCourseDetailResult>
      </GetIndividualCourseDetailResponse>
   </s:Body>
</s:Envelope>

I am going to send you a PM,

Donna

Ok, look at the request:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <tem:GetIndividualCourseDetail>
         <!--Optional:-->
         <tem:CourseId>12262</tem:CourseId>
      </tem:GetIndividualCourseDetail>
   </soapenv:Body>
</soapenv:Envelope>

Here the only element you have to add, to the <tem:GetIndividualCourseDetail> method, is <tem:CourseId>12262</tem:CourseId>, so we don't need criteria as in the previous example, just do:

$search = new stdClass;
$search->CourseId = 12262;
$values = $client->GetIndividualCourseDetail($search);

And it should work.

returning the data in xml format

The PHP Soap Client returns an object, to get it in XML you have some choices:

  • use SoapClient::__getLastResponse():

    $search = new stdClass;
    $search->CourseId = 12262;
    $client->GetIndividualCourseDetail($search);
    $xml = $client->__getLastResponse(); # will be a string
  • use a serializer to convert an object to XML, I've not tested but while searching I saw Symfony serializer was suggested;
  • use curl to make the request, or an alternative client, in which you submit the XML request generated by SoapUI.

Here's an example with Guzzle, a curl client:

<?php

    require_once './vendor/autoload.php';

    $template = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <tem:GetIndividualCourseDetail>
         <!--Optional:-->
         <tem:CourseId>%s</tem:CourseId>
      </tem:GetIndividualCourseDetail>
   </soapenv:Body>
</soapenv:Envelope>
EOD;

    $wsdl    = 'http://service.fetchcourses.ie/service/FetchCourse.svc?wsdl';
    $sopa    = 'http://tempuri.org/IFetchCourse/GetIndividualCourseDetail';
    $client  = new GuzzleHttp\Client();
    $request = sprintf($template, 12262);
    $length  = strlen($request);
    $options = [
        'body'    => $request,
        'headers' => [
            'Accept'         => 'text/xml',
            'Content-Type'   => 'text/xml;charset=utf-8',
            'SOAPAction'     => $sopa,
            'Content-Length' => $length,
            ],
        'connect_timeout' => 10,
        'timeout'         => 10
        ];

    $response = $client->request('POST', $wsdl, $options);
    $xml = $response->getBody()->getContents();

    print $xml;

And the same in pure curl:

<?php

    $template = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header></soapenv:Header>
   <soapenv:Body>
      <tem:GetIndividualCourseDetail>
         <!--Optional:-->
         <tem:CourseId>%s</tem:CourseId>
      </tem:GetIndividualCourseDetail>
   </soapenv:Body>
</soapenv:Envelope>
EOD;

    $request = sprintf($template, 12262);
    $length  = strlen($request);
    $wsdl    = 'http://service.fetchcourses.ie/service/FetchCourse.svc?wsdl';
    $sopa    = 'http://tempuri.org/IFetchCourse/GetIndividualCourseDetail';
    $headers = [
            "Content-type: text/xml;charset=utf-8",
            "Accept: text/xml",
            "SOAPAction: $sopa",
            "Content-Length: $length",
        ];

    $curl = curl_init();

    curl_setopt($curl, CURLOPT_URL,            $wsdl);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($curl, CURLOPT_TIMEOUT,        10);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($curl, CURLOPT_POST,           true );
    curl_setopt($curl, CURLOPT_POSTFIELDS,     $request);
    curl_setopt($curl, CURLOPT_HTTPHEADER,     $headers);

    $xml = curl_exec($curl);

    if($xml === false)
        error_log(curl_error($curl));

    else
        print $xml;

    curl_close($curl);

I prefer Guzzle because can use fsockopen, if curl is not available, and it follows PSR-7, but it's up to you. Bye!

P.S. I replied to your PM but I'm not sure it was succesfully sent. Will check tomorrow, now the system does not seems to be responsive.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.