PHP: Passing Interface as Parameter - php

In .NET I have done that I passed Interfaces as parameters in class methods. I want to know is it possible in PHP?
My scnerio is that I have a class dealing with mqin system functionality. Now I want to integrate Notification system with it. I want to keep notification system separate since it is not the main part of the system plus I can use it somewhere else. If I have the following structure:
Interface INotification
{
public set()
public send()
}
And then I do:
class MyClass
{
public setNotifier(INotification $notifier)
{
}
}
So Is it possible that I can access set() and send() here after implementing them in a class? I want to know how this C# Example work that they set parameters of an Interface type.
Thanks

Yes, it is possible, pretty much as you wrote. Example of such interface: http://api.nette.org/2.0/source-Http.IResponse.php.html#18 and example of such parameter: http://api.nette.org/2.0/source-Http.Context.php.html#32

Yes, you can do as you coded. You can find more information and examples on php.net.
Note that specifying the type in the method parameter (type hinting) is allowed (PHP >= 5), but not required.

Related

How to make available only those public methods which are declared in interface?

In Java, for example, this comes out of the box due to static nature of the language. But in PHP this could be also useful especially to keep a code secure and clean from an architectural point of view.
For example, we have the following code:
interface DocumentProcessorInterface
public function process();
}
class GameSaveProcessorImpl implements DocumentProcessorInterface {
public function process() {
// do something useful
}
public function methodToSetSomethingFromFriendClass() {
// setting private fields, some postponed initialization/resetting, etc
}
}
Then, from some class (lets call it "friend class", because it lies side-by-side with the GameSaveProcessorImpl class and compelements it) we call method methodToSetSomethingFromFriendClass. Because of PHP duck typing such ability to call this method is also available to any alien client code, but this method is not for such usage. Alien (external) client code MUST use only DocumentProcessorInterface methods (this is one of the reasons why we use interfaces at all).
There are some solutions that come in mind.
1) Just leave it as is, but rename public methods that are not in interfaces, so it work as warning for those alien client code implementors, for example, rename methodToSetSomethingFromFriendClass to internalUseOnly_methodToSetSomethingFromFriendClass. Reduces risk of occassional usage, but doesn't prohibits calling methods technically.
2) Using adaptor (decorator) pattern. Pass to an external code only decorated instance which doesn't has methodToSetSomethingFromFriendClass method. It does solve problem of unwanted method access but complicates another parts of our code very much. It seems there is no overall profit.
3) Not really checked yet vialibity of this idea: utilize the following fact. Base class can declare protected method so all friend classes we control may be
extended from that base class keeping our methodToSetSomethingFromFriendClass mehod marked as protected being effectively protected from external code, but callable from "friend" class. Technically this allows protection, but requires friend classes to inherit from common base class, drawbacks of such are well known.
Do you know anything better?
Links to the articles are appreciated as well as sharing experience on this topic research.

Why there is a class name before the argument name in a function declaration?

I have seen this in the MVC frameworks.
Class Hotel{
function add(AddRequest $post){
$this->save($post->all());
}
}
Here "AddRequest" is a class which has been inherited.I dont quiet get the idea of it.All i knew is it binds/validates the arguments which has been passed into the function before being used in the function.Anyone can explain this well? How is the "AddRequest" is being implemented in this code?
This is a type declaration (formerly known as type hinting). The function will reject a $post passed to the function that's not of the AddRequest type.
If you're not explicitly injecting it yourself, chances are the framework is using reflection to automatically determine and inject the required dependency. As an example, Laravel uses this fairly extensively in version 5.

Method overloading in a model of Yii framework

I want to overload two methods in a model of Yii framework.
Here, I want to say that like in Java we have method overloading concept means method has same name but differs in number of parameters pass to that method. So these similar concept can apply in PHP Yii framework's model class.
In Yii model class, I want to create two methods like,
public function test(){
//method logic
}
public function test(int parameters){
//method logic
}
Is it possible to create like these? I am getting error like "cannot define same function".
What you are talking about is not supported in PHP. You could try using default values in function arguments. For eg.
function foo($int_param = 0) // do something
You could also use func_get_args. You define your function to not accept parameters and then get the arguments using func_get_args().
These approaches are suitable if there is not a lot of difference between the functions that you're trying to implement.

How to represent an object and map between different sources/locations

I will be building a system where a particular object will originate from a web service (SOAP based). It will then be displayed on a web page (via PHP). Under certain circumstances we'll store a copy with some additional information in a local MySQL database. And from there it will be batch processed into Salesforce CRM (again via PHP). We may also subsequently pull the object out of Salesforce for display online. So alot going on. For the most part the object is the same with each subsequent node in the system likely adding a couple of fields specific to it, unique ids mainly.
I'd initially toyed with the idea of encapsulating all the necessary functionality into the one class in PHP which would deal with reading and writing from each of the appropriate sources. This felt like it was over complicating the class, and not a good approach.
I then looked at having just a container class, with no real functionality attached beyond getters and setters. Then creating separate functionality outside of this to deal with the reading and writing between the different sources, simple enough code although tedious to map between all the different field names across the different sources. There is probably a design pattern or two that apply here, but I'm not familiar with them. Any and all suggestions on how to approach this appreciated.
What you are looking is Adapter pattern. You can keep your existing code till you completely change all the classes.
I'd suggest to use a composite memento serializable into XML.
I think they may be several ways to handle that. #EGL 2-101 adapter idea is one way to do it.
Basically, you have several sources, which in O.O. jargon, are different objects. But, you want to treated like if they where a single object.
You may want to make a single class for each source, test the "connection", as if each case was the only way you where going to work with. When you have several of that classes, try to make all classes share some interface, methods or properties:
class AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class SOAPObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class MYSQLObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class SalesObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
Later, use a single class to wrap to all of these source classes.
class AnyObject extends AnyConnection
{
$mySOAPObject;
$myMYSQLObject;
$mySalesObject;
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
Later, add the code, to select which "connection" you want.
Why not separate data and operations?
Contain the core information into a class C. When web services sends this class, it is encompassed in an object of some class W. The web service pulls C and sends it to persistence layer, which creates and stores P that internally contains C, et.c.,
Akin to how data flows over a TCP/IP stack...
The way I see this after thinking about it a bit would be pretty much a class to play with your object and then serialize it.
I'd probably use something like this:
<?php
class MyObject
{
protected $_data;
public function __construct($serializedObject = null) {
if(!is_null($serializedObject)) {
$this->_data = json_decode($serializedObject);
}
}
public function __get($key) {
return $this->_data[$key];
}
/* setter and other things you need */
public function encode() {
return json_encode($this->_data);
}
public function __toString() {
return $this->encode();
}
}
Then just use it to pass it serialized to your different web services.
I think JSON would do a pretty good job on this one, because you can easily unserialize it fast in so many programming languages and it's so much lighter than XML.
DataMapper pattern is that what you're looking for.
You can have one mapper for each storage mechanism that you use and use them all with one object that represent data to business logic.
Is seems your problem is more of an architectural / design decision that pure implementation detail. (I haven't done PHP for a long while and do not know salesforce but other CRM systems)
I believe the technique/pattern that will work for you is the use of a staging area. This helps especially if you have changing integration needs and also when your source data looks different from your system model or when you have different sources to integrate from. Thus, you import into the staging area and then from the staging into your system. At each place you naturally have to map (can use metadata) and maybe transform/translate data. There will be initial effort to build this, but once it's done the step from staging to your system stays quite static/stable.
Using meta data mapping can address flexibility concerns but adds a bit of complexity on implementation. It all depends on the skills and time you have at hand for your project.
I would not have any association between the objects at all. They are used for different purposes but looks similar. period.
In .NET we use a library called automapper to copy information between different classes (like a business object and a DTO). You can build something similar in PHP, either by using get_object_vars or the reflection API.
myCopyApi.copy($myDTO, $myBO);
Say you retrieve a Car from the webservice. You can store it in a WebserviceCar, which has a property car.
Now, if you want to store that Car in the database, put it in a DatabaseCar, which also has a property car. If you want to put it in Salesforce, put it in a SalesforceCar object, which has a property car.
This way, you have one object which has the common fields and several objects which have storage-specific information.
Assuming that you are thinking about storing the actual object (serialized,encoded or whatever) in a field in the database: From my point of view the object it is never the same in two applications, as business-wise, it serves different purposes. Doing this is a kind of "cutting short" in a case where is no room for "cutting short".
Remember that mainly class represents a "category of objects" which all share same properties and behaviours. So let each application use it's own class as their purpose requires it. What can be created although is, as others suggested and as you thought, the creation of an Adapter or Factory which can be used in all the implied applications as it serves the same business purposes "translation" of objects.
Adapter pattern
Factory pattern

Something like PHP's __call() in Actionscript

Suppose (as an example) that I have a class which I want to log all method calls to.
In PHP this can be accomplished quickly and easily with __call(), or in Python with decorators.
What would be the easiest way to accomplish the same thing in Actionscript 3?
Extend flash.utils.Proxy and use the flash.utils.flash_proxy namespace. There's methods similar to __get, __set and methods for delete methods as well. For example, the __call method is:
override flash_proxy function callProperty(name:*, ...rest):*;
so if have a class that extends Proxy, you do:
var test:MyObject = new MyObject();
test.myMethodThatIsntDefined("param");
then callProperty will be called and name will be set to "myMethodThatIsntDefined" and "param" will be in the ...rest array.
The link to the asdoc has a simple implementation that should get you going. I typically use the Proxy class for something like an API. For example, back in the day I had a Flickr API wrapper that translated the name of the function call to an API method name in the Flickr API. Something like:
flickr.galleriesGetPhotos();
and in the callProperty I'd split on the first word to get the API name "flickr.galleries.get_photos". The names were different back then I think.
You can try using the Proxy class.
dynamic class MyProxy extends Proxy {
flash_proxy override function callProperty(name:*, ...rest):* {
try {
// custom code here
}
catch (e:Error) {
// respond to error here
}
}
Refer:http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/Proxy.html

Categories