On 4/7/2016 8:43 PM, Fleshgrinder wrote: > On 4/7/2016 8:05 PM, Rowan Collins wrote: >> Meanwhile, it might be worth checking the list archives for previous >> discussions of package visibility; I know it has come up a couple of >> times recently, in various forms, so it would be good not to repeat the >> same points again and again. >> > > I check what I can dig up. :) >
Here we go: # 2007-12: Namespace access modifiers http://marc.info/?t=119750415000002 # 2009-09: New access modifier http://marc.info/?l=php-internals&m=125341032112627 Some nice keyword suggestions in this one: - group - trusted - party # 2011-03: Class Access Modifiers http://marc.info/?t=129917302700001 # 2013-02: I would like to write an RFC for the addition of an internal keyword http://marc.info/?t=136194893000003 # 2014-12: Package private class http://marc.info/?t=141929489300003 # 2015-11: Internal methods proposal http://marc.info/?t=144836744000001 I am sure that I overlooked something since the search turned up a lot of stuff. However, the above list already illustrates that such a feature is often requested and useful. This is further illustrated by other languages providing similar functionality. There were various questions raised in the threads above that I would like and try to answer here. > Can child classes redeclare visibility or override it. Yes, every class in an inheritance change can open up the visibility as is already the case for methods in PHP. The reason for that is simple: namespace Process\Pipes { public interface Pipes {} abstract private class AbstractPipes implements Pipes {} protected final class UnixPipes extends AbstractPipes {} protected final class WinPipes extends AbstractPipes {} } The UnixPipes and WinPipes classes are useless if they cannot open up the visibility because they cannot be instantiated from nowhere. > It would still be possible to get an instance of a private class from > the outside, e.g.: > > namespace Internals { > private class Foo {} > public class Bar {} > public function getFoo() { > return new Foo(); > } > } > } Yes and this is intentional. The class visibility modifiers only restrict the creation of such objects and not the interaction with them at runtime. Otherwise it would be impossible to implement a public interface in a private class that is being returned to the client. public interface Entities extends \IteratorAggregate {} public interface EntityManager extends Entities {} private class InMemoryEntities implements EntityManager {} private class FilesystemEntities implements EntityManager {} private class MySqlEntities implements EntityManager {} private class PdoEntities implements EntityManager {} switch (ENV) { case PROD: $entities = new MySqlEntities; break; case TEST: $entities = new InMemoryEntities; break; } $dic->addService('entities', $entities, [ 'alias' => 'entitye_manager', ]); This is not /good code/ or anything but should illustrate the usefulness of it. In other words: It supports the I in SOLID. :) https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 -- Richard "Fleshgrinder" Fussenegger
signature.asc
Description: OpenPGP digital signature