I'm trying to do a call to a soap webservice from php.
The webservice returns an ADO.NET DataSet structure. Are there any libraries in PHP that can deal with this sort of data structures? If so, what are they called and where can I find them? If not, feel free to give tips?
So far, I have this (using ActiveMQ and the NuSoap library):
/**
* Create a new service instance
* Provide ActiveMQ uri and the extended class name
**/
$client = new Client('tcp://localhost:61613?tcpNoDelay=false', 'test');
/**
* New service reference
**/
$service = new ServiceProxy($client, 'ServiceName');
/* Service call */
$result = $service->get_clients();
get_clients() is a method that does the actual service call and it gets the DataSet structure in return. How can I manipulate this return value?
In .NET for example, there is a DataSet class. The ADO.NET DataSet contains one or more ADO.NET DataTables which in their turn consist out of one or more ADO.NET DataColumns and DataRows which are returned in a collection (array).
A simple code example, where the DataSet only contains one DataTable, can be:
/**
* Here, the val variable will contain the data positioned in the
* first field of the first DataRow of the first DataTable
**/
string val = dataset.Table[0].Rows[0].ItemArray[0];
I want to do the same in PHP, but I need a helping hand.
I would suggest you try learning more about the structure of the data you are working with. It is most likely some form of JSON or XML, which can be manipulated through the large set of PHP xml and json handling libraries.
Your first step is to look at the data being returned by your request and identifying it's format. Microsoft documents the ADO.NET API's datasets in depth HERE at the MSDN library. This should help you to make sense of what you are seeing when you inspect the data. Some data providers allow you to access the same data in different formats, depending on a parameter or a family of similar functions. Do you have documentation for your providers API?
Next, after you have identified the format and deciphered the specifics of the datasets schema, You need a class to manipulate the data. If you are dealing with something that conforms to a published standard you can use something like simpleXML, JSON or DOMXPath.This class should store the data in protected member variables and provide methods to inspect, iterate, load, refresh, search and so forth. You should refer to the PHP manual's function reference for help here and write whatever functions you need. I would write it generically to handle any similar dataset and derive a class to expose exactly the data I need for a particular application.
Another approach would be to write a COM component in a .net language to access and manipulate the data and import it's functions through PHP's COM extension. I think I would go with this choice if the data format is a weird proprietary Microsofty one.
The third possible approach works only if you have programming access to the server. If you can adapt the service provider to comply with the specification, Microsoft has released an interoperability toolkit which is supposed to act as a bridge between .net services and PHP clients using a layer of proxy objects to expose the ado.net data to PHP scripts. They throw the word RESTful around alot, but I'm not really sure what they mean by that. Check out the OData SDK for PHP HERE at Microsoft's interoperability HQ (there is info here about PHP and other Microsoft platforms and products like Azure, silverlight, Bing, etc., as well). As I said though, I think you would need the data provider to emit data which conforms to their standard. Perhaps it already does. I can't tell without a schema! If so then this is your best bet.
Good Luck!
Related
My question relates to the Tin Can PHP API library's Person object and what use may be made of it.
The library's Person object is (so far as I understand) an implementation of the Agents Resource in Part 3 Section 2.4 of the xAPI specification (link: https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Communication.md#24-agents-resource). The specification recognises a Person object and indicates that the purpose of the object is to
provide combined information about an Agent derived from an outside
service, such as a directory service
It seems from that description, and from the developers of the library (see link), that the specification's Person object is intended to provide a means of collecting, within the one object, information about a person which is dispersed among a number of different Agent objects.
I have had difficulty following the examples in the library but the following (oversimplified) code seems to work in the SCORM Cloud LRS:
...
$agent1 = new TinCan\Agent();
$agent1
->setMbox('david.jones#somehospital.gov.au')
->setName('Dr David Jones');
$agent2 = new TinCan\Agent();
$agent2
->setMbox('d.jones#medicalorg.org.au')
->setName('David Jones');
$person = new TinCan\Person();
$person
->setMbox([$agent1->getMbox(), $agent2->getMbox()])
->setName([$agent1->getName(), $agent2->getName()]);
...
Is the library's Person object intended to be saved to the LRS? If so I have not been able to find any means of doing so using the library's Statement object. If not, what is its intended use?
I would be grateful for clarification. Thank you.
The API does not provide a means to save this object. It is intended for the LRS to use whatever means it can to assemble multiple Agents that represent the same entity into the Person object. The intended purpose is to allow systems accessing the statement stream to be able to combine those streams for multiple Agents to get a fuller picture of that person's overall activity.
For example, I may have 3 (or X) identifiers that represent me as a person, let's assume they are:
mailto:dave.personal#example.com
mailto:davelastname#work.example.com
{"name": "#dave11785","homePage": "https://twitter.com"}
Passing any one of those Agent identifiers (as a full Agent representation) to the Person read only resource will return a Person object that includes all of them assuming sufficient knowledge by the LRS to map them together. For a reporting system therefore, it would be possible while it is reading the statement stream to request the Person object for each new Agent it sees and then coordinate statements with disparate actor properties (for instance) into a single record of that person's complete activity. The key here is that the LRS has to have been developed (or integrated) in such a manner that it has the requisite knowledge to associate Agents together.
TinCanPHP provides the full range of data model objects because in theory it could be used to write an LRS just as much as to communicate with one as an LRP. The key implementation detail here is that it provides the GET /agents readonly resource via the TinCan\RemoteLRS class which will provide back a TinCan\Person object. Since your code is not interacting with an instance of the TinCan\RemoteLRS class it isn't actually communicating with the LRS so SCORM Cloud's LRS is irrelevant in this case. If you were to interact using the available resource you would get a Person object returned that includes only the Agent you passed into it because (at least at the time of writing) Cloud does not know how to associate multiple Agents, but it does know that the default is the Agent provided to it.
TLDR: Writing a service (in the model layer). It talks to ffmpeg. Where should validation go? Should I create a service response object so it is testable? How should it be structured?
Background: I'm designing some classes to retrieve data from an external service. It could be an API, but in fact it's calls to ffmpeg cli, which in effect is an API to the conversion tools themselves.
When talking to an external service, where the data retrieved may not always be the same, how is it best to go about maintaining at least a consistent application state on your end so your application doesn't depend on the external service to work?
I have already separated out the classes thus far, trying to maintain SRP within them:
class CommandDispatcher { }
The Command Dispatcher's sole job is to make a request for data (to ffmpeg) and retrieve the response for that data back.
class Converter { }
The converter's sole responsibility is to take user requests (like convert 1 to 2), and send the basics to the command dispatcher which handles the exec() calls.
Here are my questions:
When talking to an external API / service, should I be creating an APIRequest and an APIResponse object (in this case an FFmpegResponse object)?
I have seen examples of this for OAuth, where there is an OAuth response object. However, that's simple enough because calls to this are done over the HTTP protocol which tends to give back at minimum an error code and a message. Calls to something like ffmpeg don't guarantee a similar response (ffmpeg may not be installed, for example). Is this object merely a domain object (i.e. an entity: some class members and setters and getters)?
Validation. If I am creating an FFmpegResponse object, whose job is it to put the data into the right members of the Response object?
Imagine ffmpeg isn't installed and the CommandDispatcher gets the response back empty. Is it up to the CommandDispatcher to then populate the FFmpegResponse object with an "ffmpeg not installed" error? Should I have a validation object do this?
Remember, I'm trying to stick to the Single Responsibility Principle here, so I'm thinking that the CommandDispatcher shouldn't care about whether the data is valid or not - it should merely ask for data and retrieve it. Where does my validation fit within the model layer for this service?
This isn't only for FFmpeg but will help for future external service calls. What is the best [practice] way to structure your code and classes to maintain SRP yet also a consistent application state regardless of whether or not the external service responds in an expected way?
In your current structure, CommandDispatcher should be either an interface or an abstract class (depending on the necessity of abstract code). You would then create a concrete implementation: FFMpegCommandDispatcher which would encapsulate the understanding of ffmpeg specific responses.
Response objects will then take on a similar structure: CommandResponse would be an abstraction with the concrete implementation FFMpegCommandResponse.
It would be best to create a set of common error conditions (serviceNotAvailable, serviceNotInstalled, serviceDiedAHorribleAndBloodyDeath, etc). Your dispatcher implementation can then set a common error code on the response object and provider implementation specific details. ('Error 1984: FFMpeg is watching you')
If you're concerned (and I would be) about validating input as well. You could create a CommandRequest abstraction, and FFMpegRequest implementation, that will take user input and make sure that it's okay to be sent to the command line.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Framework for providing API access to website?
I need to write a service in PHP. The server will be used by android/iphone clients through the url for example like this
http://www.myservice.com/query.php?param1=a¶m2=2...
The server will return data back
The client will push data to server
There can be large num of clients simultaneously accessing so the performance is key
I want to use the data format that is easily understood by my android client. In other words, I do not want to reinvent the wheel and create my own format and parsing, instead I would prefer to use any library if it exists.
Is there a framework that I can use to abstract the communication mechanism for data get and push ?
Thanks,
Ahmed
I developed a class that is the PHP native SoapServer class' REST equivalent.
You just include the RestServer.php file and then use it as follows.
class Hello
{
public static function sayHello($name)
{
return "Hello, " . $name;
}
}
$rest = new RestServer(Hello);
$rest->handle();
Then you can make calls from Java like this:
http://myserver.com/path/to/api?method=sayHello&name=World
(Note that it doesn't matter what order the params are provided in the query string. Also, the param key names as well as the method name are case-insensitive.)
Get it here.
Being the Author of Restler, I would like to suggest that you can try Restler 3 for the following reasons
It is specifically made for API creation
It handles media type conversion for you and supports many media types including
JSON
Plist (both XML and Binary)
XML
Comes with many examples to get started.
Your API is automatically documented with Restler API Explorer
well,
Use mvc framework(yii, ci, ...)
and from controller directly print json_encode($object).
It will return json data to browser, and consume it anywhere(compuer, droid, iphone, ... , iron :D). the solution is json. just share object in json format, so anyone can map it into it's preferred obejct
here is something something you may have a look
I'm building a webapp in MySQL/PHP/Javascript.
In PHP, I've got all the classes from the domain od the problem which persist in the database.
In Javascript, there is a cache with objects from the last queries.
When an object in Javascript is updated by the user, it has to update itself in server-side. Which would be the best way to do this?
Should I create a class in PHP and Javascript for communication purposes? Should each object in Javascript send an AJAX query to a different php file depending on the class of the object it needs to update?
Are there any patterns to follow to solve this?
Creating a separate PHP file for each class would certainly be more maintainable if this is a project of any size at all. It would also allow you to do things like have different server-level authentication based on the classes.
On the JavaScript side, you definitely want some sort of AJAX library, whether you throw it together yourself (I did one once in about 50 lines of JavaScript) or use one of the ones out there. You may need a helper function or two that knows how to serialize the data (XML, JSON, delimited, whatever).
You can write object oriented code in JavaScript, and if you're doing that already, it makes sense to add a write() or updateServer() method to call the AJAX library with the right parameters for consistency. If you're not writing OO code, it still may make sense to have separate functions, but only if there's more than one place you need to persist these objects from.
Most AJAX frameworks (jQuery etc) will send an 'HTTP_X_REQUESTED_WITH' header set to 'xmlhttprequest'. I like to use this to decide which view to use.
This means the same url can be used to retrieve JSON, XML, or HTML snippet via JavaScript or to return a full document if a standard GET / POST request is made.
This means your app will simply revert to normal requests should the user have JS disabled.
I think you should have a look into the RESTful API with PHP and JavaScript. You address your domain model objects as unique resources (e.g. /application/books/1). If you only want to implement CRUD functionality a generic Controller that updates the corresponding domain model (e.g using an ORM tool like Doctrine) should be sufficient.
If you really want to have the same model on the client side in JavaScript depends on your Application. I like the idea of just managing a single JavaScript object on the client side which will be loaded via REST and then populated to HTML Forms and send back e.g. as JSON (or as a simple form submit) to the server. If the client side model idea appeals to you, I recommend to have a look at JavaScript MVC which has a quite interesting model implementation.
I have a web-app-database 3 tier server setup. Web requests data from app, and app gets its data from the db then processes and returns it to web for display. Standard.
Currently all the data I serialize from app to web gets put into custom defined data structs that the web side then parses for display. In other words, say I have an order that I want to retrieve and send to web. I don't serialize the whole object, but rather build an array with the appropriate data elements while on the app server, then serialize that array over to the web servers.
Now, I am looking into serializing the entire order object over to the web server.
What is the best method you guys have found to serialize objects while maintaining separation of appserver and webserver code? I don't want my webservers having any code which accesses the DB, but I want them to reuse the classes that encapsulate my order and other data as much as possible.
To further refine my question (thanks to Glenn's response), I don't want my webservers to have any of the business logic around say the order class either, that only the appserver needs to know. The objects already use separate serialization to/from the database, and to/from the webservers.
Using the order example, on the appserver, an order should be able to cancel: ie
$order->cancel();
but on the webserver that method should not even be found. It shouldn't simply proxy back (directly) to the appserver order's cancel method, because user action requests should flow through the application's authorization and permissions checking layer.
So how do I get an order object on my webserver that has some (but not all) of the methods and properties of the object on my appserver, with little to no code duplication. One thing I've been thinking is to create a base class with a limited set of properties and methods. It would use an inner class to hold its properties, and I would require all data access to pass in and out of getters and setters. These would in turn call the getters and setters on the inner class.
The web and app servers could then independently extend the base class, and use a custom inner class to hold the properties. Then on the app side for instance, the inner class could be an ORM class extention that can persist data to the DB, and on the web side the inner class could be a simple properties holder class.
But the whole inner class thing seems a little clunky, so I'm still looking for better solutions.
Factor out format specific
serialization code into separate
classes using the Adapter
pattern. Your problem domain
classes become backing store
neutral.
Use relational database specific adapter classes on the app tier to serialize objects to and from the data tier.
Use HTML specific adapter classes on the web tier to serialize objects to and from the web browser.
Use XML (or whatever wire protocol friendly format you deem most appropriate) specific adapter classes on both the web and app tiers to serialize the objects between the web tier and the app tier.
You get extra points if you are clever enough to figure out how to make these adapter classes generic enough such that you don't need a different set of adapter classes per problem domain class.
If I understand your question correctly, you want to serialize the data of your objects, but when they are re-hydrated, they should be so into a different type of object (With limited and/or different functionality)?
You can do this in different ways, depending on what protocol you prefer. For example, you could use SOAP. You should then hydrate the objects into a different class on the client-side, than on the server-side. You could also use PHP's native serialization and either a) Have a different code base on the client (Could get confusing) or b) mock a bit around with the serialized string (Eg. replace the class-name). A crude example can be found in the comments for the PHP manual.