简体   繁体   中英

PHP: using type hinting (scalar types & return types) for namespaced instances

What is the best way to handle scalar type & return type declarations for namespaced instances?

I use namespaced classes for everything and use the 'use' aliases at the top of the class for all classes that will be used in the file.

This is an example without using scalar type & return type declarations:

file 1

use Model\ExampleA\ClassA;
use Model\ExampleB\ClassB;

$classA = new ClassA();
$classB = new ClassB();
$result = $classB->action($classA);

file 2

namespace Model\ExampleB;

class ClassB
{
    /**
     * @param  ClassA $classA The ClassA instance.
     * @return ClassA         Returns the ClassA instance.
     */
    public function action($classA)
    {
        return $classA;
    }
}

Now if using scalar type & return type declarations, file2 will instead be:

namespace Model\ExampleB;

use Model\ExampleA\ClassA;

class ClassB
{
    /**
     * @param  ClassA $classA The ClassA instance.
     * @return ClassA         Returns the ClassA instance.
     */
    public function action(classA $classA) : classA
    {
        return $classA;
    }
}

So if using scalar or return type declarations for namespaced instances, I have to use the 'use' alias again at the top of file2 just for the type hinting to work.

I would much prefer to use the 'object' data type for scalar type or return type for namespaced instances and keep the @param and @return data types in the docblock as the instances like this:

namespace Model\ClassB;

class ClassB
{
    /**
     * @param  ClassA $classA The ClassA instance.
     * @return ClassA         Returns the ClassA instance.
     */
    public function action(object $classA) : object
    {
        return $classA;
    }
}

Is this OK? Or is my other example the best way to do this?

I don't really understand your problem.

  1. If both classes (ClassA and ClassB) are in the same directory, no need to use the use statement.

  2. Scalar type will indicate to your colleague that your method need an instance of this class. This is useful, it documents your code and prevent bugs. See that as a guideline.

Of course your comment will indicate the same thing but the problem is: comments can lie. If somebody modify your code and not your comment to accept an object ClassC (for example) instead of ClassA, it will bring quite some confusion. Imagine a whole codebase like that.

I saw misleading comment creating nasty bugs. More than once.

  1. A use statement at the top of your file doesn't cost anything. Even better: if you have a lot of them, it's a good indicator that your class should be split to respect the SRP. Plus it describes your dependencies. It's always good to know what you can affect when you modify your code.

Conclusion: I would suggest that you use scalar and return types and don't be afraid by the use statement.

To explain a bit why namespaces were introduced in PHP:

Namespaces allow you to have different classes with the same name located in different filepath without having any name collision. If you have two classes called ClassA, how the interpreter can know what ClassA you want to use?

Since your two classes with the same name need to be located in different folders, your namespaces will be different. PHP will know what class to use. It has nothing to do with class instantiation.

Before the namespaces you had some nasty class names like Mage_Application1_Entity_Model.php which was describing the filepath. Ugly as hell.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM