PHP use and namespaces

Please use this forum to ask for a new feature or to change an existing feature.
Merci d'utiliser ce forum pour demander de nouvelles fonctionnalités ou la modification de fonctionnalités existantes.

PHP use and namespaces

Postby fbernoldi » Tue 3 Oct 2017 14:05

Hi,

In PHP you can do something like:

Code: Select all
<?php

namespace Test;

use \SomeNamespace\SomeClass;
use \SomeVeryLargeAnoyingNamespace\SomeVeryLargeAnoyingClass as SVLAC;

class Test {

    public function dependency() {
        $s = new SomeClass;
        $svlac = new SVLAC;
        $svlac2 = new \SomeVeryLargeAnoyingNamespace\SomeVeryLargeAnoyingClass();
    }

    public function someNiceMethod(SVLAC $hello) {
        // something php 7 friendly
    }

    /**
     * @param SVLAC $hello some hi hi.  (@param ${t0} ${p0} ...)
     */
    public function someNiceMethodUntyped($hello) {
        // something php 5 friendly
    }

    /**
     * @param SVLAC $hello some hi hi. (@param ${t0} ${p0} ...)
     * @return SVLAC (${type})
     */
    public function someNiceMethodReturning(SVLAC $hello) : SVLAC {
        // something php 7.1 friendly
        return $hello;
    }

    /**
     * @param \SomeVeryLargeAnoyingNamespace\SomeVeryLargeAnoyingClass $hello Some hello thing
     */
    public function someUglyMethod(\SomeVeryLargeAnoyingNamespace\SomeVeryLargeAnoyingClass $hello) {
        // something else
    }

}


Currently there is a force namespace prefix but I can't find a way to use it this way, it's quite demanding to add the uses you need to artifacts manually.

So the feature request would be that the current "import" dependency generates a PHP use statement at least so you can use the alias "SomeClass" instead of "\SomeNamespace\SomeClass", I don't know how to solve the "SVLAC" alias case.

And for the methods like "someNiceMethod" to generate a PHP use statement automatically and use it when the force namespace prefix is not set (for example).

These features would be very useful for big projects with a lot of namespaces!

Thanks,
Federico.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Re: PHP use and namespaces

Postby Bruno Pagès » Thu 5 Oct 2017 16:05

Hello,

About force namespace prefix, supposing the class A and B are in same package P and A extends B :
  • if force namespace prefix is not set the generated code is class A extends B ...
  • if force namespace prefix is set the generated code is class A extends \P\B ...

Yes, currently the uses have to be added to artifacts manually.

The dependencies are already used to generate code, they allow to generate additional require_once whatever their stereotypes. Let's note the require_once are automatically generated, for instance if A has an attribute of type B and A generated in A.php and B generated in B.php, the code generated in A.php will contain require_once 'B.php'; even it is not explicitly required through a dependency

I can modify the dependency management between two classes, for instance for a dependency A - - -> B :
  • if the stereotype is use the generated code in A.php will be a use B; (if necessary with the namespace where B is)
  • if the stereotype is use-as FOO the generated code will be a use B as FOO; (if necessary with the namespace where B is)

So the feature request would be that the current "import" dependency generates a PHP use statement ...

And for the methods like "someNiceMethod" to generate a PHP use statement automatically and use it when the force namespace prefix is not set (for example).


I don't understand, the same use form is generated in both cases, when there is a dependency for the first case, without dependency in the second case, what is the interest to have a dependency ?
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 474
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: PHP use and namespaces

Postby fbernoldi » Mon 9 Oct 2017 19:40

Hi Bruno,

Bruno Pagès wrote:Hello,

About force namespace prefix, supposing the class A and B are in same package P and A extends B :
  • if force namespace prefix is not set the generated code is class A extends B ...
  • if force namespace prefix is set the generated code is class A extends \P\B ...

Yes, currently the uses have to be added to artifacts manually.

The dependencies are already used to generate code, they allow to generate additional require_once whatever their stereotypes. Let's note the require_once are automatically generated, for instance if A has an attribute of type B and A generated in A.php and B generated in B.php, the code generated in A.php will contain require_once 'B.php'; even it is not explicitly required through a dependency

I can modify the dependency management between two classes, for instance for a dependency A - - -> B :
  • if the stereotype is use the generated code in A.php will be a use B; (if necessary with the namespace where B is)
  • if the stereotype is use-as FOO the generated code will be a use B as FOO; (if necessary with the namespace where B is)

So the feature request would be that the current "import" dependency generates a PHP use statement ...


Great!

Bruno Pagès wrote:
And for the methods like "someNiceMethod" to generate a PHP use statement automatically and use it when the force namespace prefix is not set (for example).


I don't understand, the same use form is generated in both cases, when there is a dependency for the first case, without dependency in the second case, what is the interest to have a dependency ?


The goal is that BoUML generates the short class names according to the uses declared, for dependencies, associations and method signature.

i.e. for an association:

Code: Select all
<php

use SNamespace\SClass;

class HelloClass {

    /**
     * @var SClass this could be an association with stereotype "use" with return type SNamespace\SClass using ${type} in documentation.
     */
    private $asociated_instance;

}



For a method signature:

Code: Select all
<php

use SNamespace\SClass;

class HelloClass {

    /**
     * @param SClass $sclass some typed ${t0} param
     * @return SClass some return ${type}
     */
    public function hello (SClass $sclass) {
        // ...
        return $sclass;
    }

}



I hope I explained better with separated examples.

Regards,
Federico.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Re: PHP use and namespaces

Postby Bruno Pagès » Sat 21 Oct 2017 21:13

Hi Federico,

Bouml 7.1.3 is available and add use generation

Please refer to the historic for details

Regards,
Bruno
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 474
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: PHP use and namespaces

Postby fbernoldi » Sun 22 Oct 2017 10:40

Hi Bruno,

Thank you very much! I'll look into it and give it a try :)

Regards,
Federico.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Re: PHP use and namespaces

Postby fbernoldi » Mon 23 Oct 2017 17:11

This is great! I've started using it for new classes and to replace existing uses on project model I have and I've found some issues:

1) When the use belongs to the same namespace route, bouml generates partial use path.

i.e for "Cat" belonging to "\Animals\Mammals" namespace, a realization dependency stereotyped as "use-as Feline" to "\Animals\Mammals\FelineInterface":

bouml generates:

Code: Select all
<?php

namespace \Animal\Mammals;

use FelineInterface as Feline;

class Cat implements Feline {
   // ---
}



For PHP this is not correct since it expects a full definition path, and the generated "Feline" use is referencing to "\FelineInterface" instead of "\Animals\Mammals\FelineInterface". Adding a full path to use statement corrects this.

should be:

Code: Select all
<?php

namespace \Animals\Mammals;

use \Animals\Mammals\FelineInterface as Feline;

class Cat implements Feline {
   // ---
}



This is the most important fix for me to use this feature everywhere.

2) When I was testing case one I've found that when you change the regular realization of FelineInterface to a stereotyped "use-as Feline" realization, php generator skips the require_once statement.

i.e generated regular FelineInterface realization:

Code: Select all
<?php

namespace \Animals\Mammals;

require_once 'animals/mammals/FelineInterface.php';

class Cat implements FelineInteface {
   // ---
}



generated stereotyped "use-as Feline" realization with the same artifact:

Code: Select all
<?php

namespace \Animals\Mammals;


use FelineInterface as Feline;

class Cat implements FelineInteface {
   // ---
}



I normally don't use require_once since I use autoloaders for classes, but maybe it's an issue for someone. Most actual php projects autoloaders instead of require statements.

For stereotyped "use" and "use-as" realizations the require_once is not created.
For stereotyped "use" and "use-as" dependencies the require_once is not created.
For stereotyped "use" and "use-as" associations the require_once is not created.
For stereotyped "use" and "use-as" generalizations the require_once is created correctly.

3) Roundtrip PHP:

- Works fine for "use" and "use-as" stereotypes for generalizations.
- Ignores "use" and "use-as" stereotypes for realizations and dependencies.
- I think that roundtrip is treating every association as an attribute, (maybe it needs to check if the attribute in the file is an association in the model?), also not working for "use" and "use-as" associations.

Roundtrip is a great feature, this errors in most cases have no impact or they are easy to fix since the feature does not automatically delete these changes, it's just un mark them and delete the created "unknown" new classes or i.e. the "duplicated" realizations.

4) Provide a way to add documentation to use dependency?

for example:

Code: Select all
<?php

namespace \Animals\Mammals;

// Feline interface to use on cats.
use \Animals\Mammals\FelineInterface as Feline;

class Cat implements Feline  {
   // ---
}



In bouml if we add a @{meow} and set the value to "// Feline interface to use on cats." and we add it to the PHP declaration as:

Code: Select all
@{meow}
${type}


it gets replaced as:

Code: Select all
<?php

namespace \Animals\Mammals;

use \Animals\Mammals\Feline;

class Cat implements // Feline interface to use on cats.
Feline  {
   // ---
}



This is not a priority, the same documentation could be written elsewhere by some other means.

Thanks for your time.

Regards,
Federico.

PS: I've edited and drafted this many times so I might write a little nonsense somewhere.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Re: PHP use and namespaces

Postby Bruno Pagès » Mon 23 Oct 2017 18:36

I am quite desperate :?

fbernoldi wrote:1) When the use belongs to the same namespace route, bouml generates partial use path.

I compute the path like for the other cases, the fact use doesn't allow that is a pity

While we are there, a partial path is legal when referencing a class for instance in an inheritance or I am always wrong ?

fbernoldi wrote:2) When I was testing case one I've found that when you change the regular realization of FelineInterface to a stereotyped "use-as Feline" realization, php generator skips the require_once statement.

...

For stereotyped "use" and "use-as" realizations the require_once is not created.
For stereotyped "use" and "use-as" dependencies the require_once is not created.
For stereotyped "use" and "use-as" associations the require_once is not created.
For stereotyped "use" and "use-as" generalizations the require_once is created correctly.

:shock: The stereotype use and use-as are only relevant for the dependencies, I never speak about them for the other relations

In case a required_once is generated out of a dependency, the fact you have a dependency stereotyped use or use-as AZE changes nothing, the required_once is still generated

If the require_once was generated by a dependency and you modify this dependency to set its stereotype to use or use-as AZE, of course the required_one is not any more generated. To have both of them you need two dependencies

fbernoldi wrote:3) Roundtrip PHP:

- Works fine for "use" and "use-as" stereotypes for generalizations.
- Ignores "use" and "use-as" stereotypes for realizations and dependencies.

As you can see in the historic of the 7.1.3 there is no new version for the reverse nor roundtrip. While the reverse/roundtrip do not create dependencies for use and use-as forms but put them in the textual definition of the artifacts it is normal and expected the roundtrip deletes them

Again the stereotypes use and use-as are only relevant for dependencies

fbernoldi wrote:4) Provide a way to add documentation to use dependency?

I did not remember that I was doing this for other kind of relations :roll:
It is strange I do not allow ${comment} or ${description} in place of the complicated alias way :?
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 474
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: PHP use and namespaces

Postby fbernoldi » Tue 24 Oct 2017 10:50

I compute the path like for the other cases, the fact use doesn't allow that is a pity

I don't know why, the docs state that you have to use full class path when importing: http://php.net/manual/en/language.namespaces.importing.php

While we are there, a partial path is legal when referencing a class for instance in an inheritance or I am always wrong ?


You are not wrong here, this is correct and can be used.

The stereotype use and use-as are only relevant for the dependencies, I never speak about them for the other relations


Sorry! I think I just got carried out, I start writing these stereotypes to all my long class name relations (dependencies, generalisations, realisations, etc) to get an alias and use it.

It works in every case and that is very comfortable to model and code applications, since I don't have to create for example a dependency with stereotype use to get an alias for the parent class and another dependency to get an alias for the realisation.

To achieve this:
Code: Select all
<?php

namespace SomeNS;

use A\B\C\D;
use X\Y\Z;

class E extends D implements Z {
    //...
}


You just add stereotype use to the generalisation and realisation :)

In case a required_once is generated out of a dependency, the fact you have a dependency stereotyped use or use-as AZE changes nothing, the required_once is still generated

If the require_once was generated by a dependency and you modify this dependency to set its stereotype to use or use-as AZE, of course the required_one is not any more generated. To have both of them you need two dependencies


This is understandable using a dependency with stereotype use or use-as just to get the use statement :mrgreen:

As you can see in the historic of the 7.1.3 there is no new version for the reverse nor roundtrip. While the reverse/roundtrip do not create dependencies for use and use-as forms but put them in the textual definition of the artifacts it is normal and expected the roundtrip deletes them

Again the stereotypes use and use-as are only relevant for dependencies


My bad to try use and use-as on everything :oops:

I did not remember that I was doing this for other kind of relations :roll:
It is strange I do not allow ${comment} or ${description} in place of the complicated alias way :?


Well, again I got carried out and add use and use-as to everything and I thought: "What if I can add a description here? maybe I can type something in the relation/dependency/generalisation/etc description and add it as a comment for the use?"

-----
Having said that, I understand that it was meant only for dependencies, but it really helps a lot and it's easier to implement if you can also stereotype realisations and generalisations to get the use alias, because if there is one of those, it means that the class name you are aliasing it's written in the code, for associations you may or may not write the class name it in the code.

Besides, it's working (with the full class path name exception) if you are using autoloaders and you do not need the 'require_once' which is my case.

Thank you :)

Regards,
Federico.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Re: PHP use and namespaces

Postby Bruno Pagès » Tue 24 Oct 2017 15:15

fbernoldi wrote:I don't know why, the docs state that you have to use full class path when importing: http://php.net/manual/en/language.namespaces.importing.php

I will fix that

fbernoldi wrote:... it really helps a lot and it's easier to implement if you can also stereotype realisations and generalisations to get the use alias.

For me this is a dirty choice, the production of the use(-as) is global to the file, to put it on for instance a generalization would only make sense if the scope of the use was limited to that generalization
ImageAuthor of Bouml
Bruno Pagès
 
Posts: 474
Joined: Mon 20 Feb 2012 08:23
Location: France

Re: PHP use and namespaces

Postby fbernoldi » Tue 24 Oct 2017 19:25

For me this is a dirty choice, the production of the use(-as) is global to the file, to put it on for instance a generalization would only make sense if the scope of the use was limited to that generalization


It's that or have a dependency to the parent class with the stereotype use, it's not quite clean either way.

Anyways, both ways are way better than have extremely long class names or harcoding "use" on the artifacts or using @{use} or something.
fbernoldi
 
Posts: 33
Joined: Mon 10 Jul 2017 13:15

Next

Return to Change requests / Demandes d'évolution

Who is online

Users browsing this forum: No registered users and 2 guests

cron