Let's say you are building an API that other people will work with.
And you use typehinting a lot for functions, like function foo(array $arg){...}. This forces the argument to be an array, so passing traversable objects to this function won't work. But your function can work with such objects.
Do you think it's a good idea to remove the hint and handle traversable objects too? Or should I leave that to the user? (she can use iterator_to_array for example)
You might remove the type hint I suppose and put a PHPDoc comment. on saying it takes an array, a traversable or even arrayaccess.
It's not bad the user to give flexibility when they use your API, however your API should work fault tolerant when handling arguments that are not of the appropriate type. So if you remove the type hinting, you should add type controls to your methods (of course you don't have to but it might be considered as a best practice). However making checks causes your API to slow down (it might be negligent and might be considered a micro optimisation however if your API needs to work fast you should also consider this).
Related
Should I type hint everything (parameters and return values) whenever possible? And maybe even strive to write code that can be type hinted? In the real world with real developers which may or may not be less than stellar is there any drawback to type hinting whenever possible?
In my mind, code that breaks fast and furious is one that breaks before it can enter production most of the time.
Type hinting is the way to go. I would start with type hinting arguments (combined with interfaces), return values, and whenever you initialize a variable or property. Combined with doc blocks, and you have just documented your code in a way that allows others to pickup quickly.
function getValue(\Settings\Bar $foo) : string
{
$val = (string) $foo->value;
//..
return $val;
}
$myVal = (string) getValue($bar);
If anyone makes a mistake, the debugger will pinpoint you the exact location. Moreover use
declare(strict_types=1);
at the top of all your php pages to enforce type hinting and you are on your way to write enterprise level code using PHP.
Type hinting helps other developers or even you to understand the code better without deep diving into it. You don't have to understand internal logic of a class or a function, or search a manual or the Internet to know the type of a value that this or that function returns.
It also helps to prevent one from making silly errors. For example, one thinks that a function accepts an ArrayAccess object, but in reality, the function accepts just arrays which might cause an error.
The only drawback I can see is that it's hard to maintain type hinting and keep everything consistent due to nature of PHP itself.
So, it's heavily recommended to do type hinting whenever it's possible. With modern IDEs like PHPStorm it becomes pretty easy to maintain type hinting and keep it up to date and consistent.
First of all let me tell you that programming is my hobby (love programming) and even though I have taken some programming classes in college (C++) and have created some small programs in C++(QT), Objective-C, PHP and now Swift, I have never had the need to heavily use custom objects other than create instances, call some functions/methods from those objects or inherit from one to the other, all pretty simple stuff. The one thing that has been bothering me and that I think is the heart of the OOP world is understanding the concept of creating and using custom objects. I know this question is something I should have asked long time ago, shame on me.
Can someone be so kind and create a quick and simple example of how and what functionality is usually involved when creating custom objects?
Here I'm using Swift but this could be in any other language:
// custom object
class ClassA{
// what functionality could fit here
}
class ClassB{
init(customObject:ClassA){
// when would you pass a custom object to this class?
{
func returnCustomObjec()->ClassA{
// when would you return a custom object?
}
func passCustomObject(customObjec:ClassA){
// when would you pass a custom object?
}
}
FYI - I know when to return or pass, Stings, Ints, Doubles, etc. but I want to see when would make sense to create functions that return or accept custom objects in a real program.
IMHO the most basic use of custom objects is return types of functions. Lets say I want to write a function that returns an int a double and a string then I could do this by passing references:
void foo(int& a,double& b,string& c);
However, in this way it is not so clear that these parameters are only for return values. And also now the caller has to take care to declare (and maybe initialize) these 3 variables and has to give them reasonable names. If the return type is lightweight and copying is not a problem, this can be done like this:
struct foo_returnType {
int a;
double b;
string c;
}
foo_returnType foo();
Now there is no confusion whether its return values or parameters and more importantly if the function returns those 3 parameters, it is very likely that they logically belong together and this should be reflected in the code. I can give them a reasonable name (maybe something better than foo_returnType) and for convenience I can provide some more nice features for this new type (e.g. overloading ostreams << operator to print the type on the screen with some additional meaningful information on the meaning of the 3 parameters).
Oh my, there is a lot, lot of cases that does this. I just made some object that deal with uniform shaders in opengl. See my simplified code. There is a lot of object involved here:
Shader ShaderManager::load(Camera* camera, Entity* entity) {
Shader shader;
shader.addUniform("transform", make_unique<TransformUniform>(camera));
shader.addUniform("color", make_unique<Vec4Uniform>(entity->getColor()));
return shader;
}
And even color is an object, a very simple struct, but still an object. I rarely deal with primitives, but again some of my object act as primitive (I'm in C++, dynamic allocation is a choice)
I have a php backgound. I messed around a bit with c++ and java, but this answer is in a php perspective.
In php, custom objects are the objects which actually do things (in java there are a lot of libraries if I understand correctly, one might be able to do a lot without any custom object). That is, objects representing your business entities, such as an invoice or a sale item, or representing your application, such as a http response object, or a template parser object.
Passing and returning custom objects ensures that your methods will have a predictable behavior, that is, not calling non-existing methods on your objects, being sure that if you type-hint an interface in a method, any object that implements the sumable interface will be able to be sumed (for example).
The purpose of passing and returning cutom objects is to ensure of an application's behavior
I'll start by saying that I know how PHP interfaces work and how to "use" them.
My question is rather; how do they become useful in real life applications?
I've been writing PHP for over 3 years now and have never felt the need for an interface. I am writing interfaces more for good practice than for a particular purpose.
I'll provide an example where I've used interfaces in my own real-world experience.
Interfaces are extremely useful when you need to define something like a plugin architecture. Suppose your application accepts authentication plugins, allowing your end user implementers to integrate with their own internal auth infrastructures (LDAP, Shibboleth, some custom auth database, whatever). In order for a plugin to be compatible, it must implement the following methods:
validate_user()
start_user_session()
logout_user()
get_user_details()
If defined in an interface, a class then implements the interface ensuring that the necessary methods are present for compatibility with the plugin architecture.
Unfortunately, PHP does not enforce the return type of interface methods, so you must simply take care to document the expected return functionality of your methods.
They are not so useful - yet. Their main purpose seems to be for type hinting. When you write two separate classes that implement the same interface, you can use that interface in the type hint for a function. That way, you know you got all the methods of that interface available in the object that is passed in the parameter.
Unfortunately, PHP doesn't actually check if any called methods or properties you call on that parameter are actually in that interface, so you can accidentally use an object property that is not available in the interface, causing potential bugs when an object of a different type is passed.
Other languages are much stricter in this situation and will only allow you to use only that functionality that is declared in the interface.
Nevertheless, they are convenient for this purpose in PHP too, and maybe these checks will become stricter in future versions, so it becomes less error prone.
Check out the Standard PHP Library (SPL)
http://php.net/manual/en/book.spl.php
Countable and RecursiveIterator might give you a clue.
Working through several layers of an MVC architecture designed program, I find that I would like to have more information on a deeper layer's method return result, and that it's not always that I can anticipate when I'll need this information. And - for abstraction sake - I might not want that method outputting stuff to the application-specific log (that method could be used in a different program), or have a specific application dependent behaviour like other layers above.
For instance, in a given utility function I might have several pre-requisite checks before executing an action, that fail. If I return false on any of them, the caller doesn't know what happened. If I return false and log to the application log what happened, I'm bounding that function to application specific behaviour.
Question is: is it good/common pratice to implement a little class called MyResult and have it return the response status (ok/false), a message, an eventual integer code, and an object placeholder (array or object) where the caller could access the returned object? This MyResult class would be used throughout the whole system and would be a common "dialect" between all methods and their callers. All methods would then return an instance of MyResult, all the times.
Could you give an example? It seems a bit, but I can be mistaken, that you are having methods you are using statically (even if they are not implemented/called like that they could've been). The basic example of the table-object that can paint itself is called like so: $myTable->paint();. It can return a variable if it worked or not (true/false) but any other thing (like logging) is a function of table() and neither your calling method, nor the return value should have anything to do with that as far as I'm concerned.
Maybe I'm having a hard time understanding what situation you are going to use this for, but if you want to send messages around for some purpose that requires messages (or events etc) you should define those, but I don't see any merit in defining a default returnObject to pass around method-call results.
For errors you have two options: exceptions (that is: things you really don't expect to happen and should halt execution) and errors: expected but unwanted behaviour. The first should be left alone, the second can be tricky, but I'd say the object itself should contain a state which makes it clear what happened.
That's what exceptions are for. You don't have to over-do them like Java, but they exist because error codes suck.
If a framework does not offer a specific feature you need, there is no other way then that you take care on your own. Especially if you need something that runs cross the aims of the framework, so would never make it in.
However, many frameworks offer places in which you can extend them. Some are more flexible than others. So if possible I would look if you can still implement your needed feature as a type of add-on, plugin or helper code that can stay within the frameworks terrain.
If that is not possible, I would say it's always valid to do whatever you want to do. Use the part of the framework that is useful for you.
I work in php, and the concept of interfaces seems to me a little useless here. From reading, I understand that interfaces are part of "design by contract", but without at least guaranteeing a return of a type of a particular kind, there really isn't any contract. It seems it's like a contract that reads, "We agree to do the following: '' " -- there are no terms of the agreement.
If I want a guarantee that an object has a method, it doesn't seem like interfaces are particularly useful. If I try to call a method that an object doesn't have, I get a Fatal Error, so I find out pretty quickly that that class doesn't have a method with that name. If I want to be smart and check beforehand whether a class has a method, then checking the interface, and seeing whether the object implements that interface doesn't seem to save me any more time than just checking that object directly ( which I would do anyways to see if the class had that method regardless of any interfaces it did or didn't implement).
In other words, just because I have a set of methods that have particular names, that doesn't guarantee me any particular behavior. If I'm guaranteed a return of a variable of a certain type, I at least have some inkling of what the output would be, and I can write code that uses an object with that interface, because I know what I'm getting out of it. If it returns a string, I can continue coding with at least the certainty that I'm dealing with a string output afterward. So I'm guaranteed at least some behavior when a return type is specified. Is guaranteeing behavior part of what interfaces are for, or no?
The only thing I can think of is that when I'm writing code, it serves as a post-it note to myself to be sure to create certain methods when writing that class later on. It seems more like scaffolding for when I'm writing the code; I don't see much benefit from when I'm actually using it. So it's more for me to keep the standard when I'm creating classes than when I'm writing them. This benefit doesn't really seem to be captured in the concept of design by contract.
What benefit(s) do you actually get from using an interface in dynamic/loose-typed languages like PHP? Are they great, or is it something that more robust OO languages implement, so PHP implements it also?
Interfaces are used when you actually expect an object to implement a method.
For example, if I'm building a DB wrapper and it supports behaviours, which you register yourself in a bootstrap, then before running your behaviours (for example, sluggable), I will check that they implement my "DB_Wrapper_Behaviour_Interface" by using:
if(!($behaviourObject instanceof DB_Wrapper_Behaviour_Interface)) {
throw new Exception("Your behaviour doesn't implement my interface");
}
Design by contract is made more difficult without return types, but don't forget to favour 'tell' over 'ask'.
I believe an interface to be something like a responsibility. You are coding and need a collaborator. You ask it to do something because the code you are working on can't do everything. So you're asking another object to do something. An interface guarantees that the collaborator will do the job, but hides the 'how' it's done part.
Now you could argue that there's no need for the formal contract here, since the system will throw an error anyway if the collaborator can't do what you're asking it to do. But I think that misses the point in using interfaces as a responsibility.
Getting a fatal error is not always "easy". Sometimes you have to go on a specific module/action to see that something is actually missing in your class.
The interface enables you to make sure every method is implemented and to document these method (what the parameters are exactly going to be, what the return values should look like). This is useful if the parameters/values are arrays with a particular structure and you don't want to use classes instead (for the sake of simplicty).
I want to note, that PHP 5.4 will support type hinting. Right now I think there is only type hinting for function arguments, but I suppose there will be for return values, too. (At least there already is an RFC, though a very old and outdated one.)