This sort of thing would be useful. Drupal and Symfony both mark methods in
their libraries that aren't supposed to be used externally, but people do
anyway and then they get mad at the framework developers when they decide
to rearrange what are supposed to be internal methods.

I wrote a userland assertion to enforce just this sort of thing - enforcing
Java's notion of protected on methods otherwise marked as public. It worked
by looking up the caller in the debug_backtrace and checking to see if the
namespaces matched. To keep the impact of this check minimal I used
assert() for the check so that it wouldn't bog down production (where,
presumably, no new code would be written).

Now, the above worked, but you could hack in by lying about your namespace
in your file declaration.  Since, at the end of the day, PHP's notion of
namespace is entirely a string replace with no other enforcement there's no
way I can see of changing this short of fundamentally changing how PHP
handles namespaces.  But I wonder if that should be bothered with since
someone would have to go considerably out of their way to make a call to a
method they weren't supposed to, and they only have themselves to blame if
this sort of solution becomes unstable.

Next thing to consider - we have the problem of having already used the
protected keyword in PHP, and honestly I prefer PHP's interpretation of the
word. However, PHP doesn't have class scope at this time, so one
possibility is to allow class scope to set a default scope of the unscoped
methods and members of the class. So...

public class A {
  function foo () {} // Callable from anywhere.
}

protected class B {
  function foo () {} // Callable only from current namespace, or any child
namespace.
  public function moo() {} // Callable anywhere. In effect the method
specific scope overrides class scope.
}

private class C {
  function foo () {} // Callable only from the same namespace, no children
can access. This includes a extending child function from another namespace
  protected function moo () {} // Callable from any child class regardless
of that child's namespace.
}

That could work. Feel free to poke holes in this - I'm sure I've missed
something.

On Sat, Sep 19, 2020 at 7:43 AM Rowan Tommins <rowan.coll...@gmail.com>
wrote:

> On 17/09/2020 13:28, Olle Härstedt wrote:
> > We have public, protected and private. Since PHP has no module system, we
> > have no qualifier to mark a class property as "private for this module".
> > One solution to this could be to add a new qualifier "internal", to make
> > properties public within the current namespace.
>
>
> As well as the implementation details of doing this at run-time (which
> is where PHP does all its access checks right now) the mapping of
> "namespace" to "module" is not necessarily the most useful one.
>
> For instance, if you define an "internal" property in a class called
> Acme\Frobulator\Handlers\TextFile\Format\CSV, it would be accessible in
> other classes in namespace Acme\Frobulator\Handlers\TextFile\Format\ and
> possibly also sub-namespaces like
> Acme\Frobulator\Handlers\TextFile\Format\Exceptions, but not in other
> parts of Acme\Frobulator\Handlers\TextFile or Acme\Frobulator as a whole.
>
> If Acme\Frobulator was the root of the Composer package, the only way to
> make something internal to the package as a whole would be to flatten
> everything into that root namespace, like
> Acme\Frobulator\Handler_TextFile_Format_CSV
>
> That leads me to think that if we do want "module"-level features - be
> it internal classes, internal properties, or module-level declare()
> settings - we need a way for the user to define that separately from the
> fully-qualified namespace.
>
> Regards,
>
> --
> Rowan Tommins (né Collins)
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

Reply via email to