rfc:nested_classes
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:nested_classes [2013/09/29 17:48] – created krakjoe | rfc:nested_classes [2013/10/01 23:45] – [Private Classes] krakjoe | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Nested Classes ====== | ====== PHP RFC: Nested Classes ====== | ||
- | * Version: 0.1 | + | * Version: 0.2 |
* Date: 2013-09-29 | * Date: 2013-09-29 | ||
* Author: Joe Watkins, krakjoe@php.net | * Author: Joe Watkins, krakjoe@php.net | ||
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
Line 13: | Line 13: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | I propose that we have the simplest version of class nesting that is useful, rather than creating new access checking routines and declaring public/ | + | A nested |
- | * A nested | + | <code php> |
- | | + | class foo { |
- | This makes nested classes implicitly private; which is the best use case of a nested class anyway. | + | |
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
- | The following | + | '' |
+ | |||
+ | A nested | ||
<code php> | <code php> | ||
- | <?php | + | class foo { |
- | namespace io { | + | |
- | | + | |
| | ||
- | class FileReader { | + | |
- | class ZipFileReader | + | } |
- | class Buffer implements IOBuffer | + | </ |
- | + | ||
- | | + | The first and second examples given here are therefore the same, by default classes are public, just like class members. |
+ | |||
+ | The following describes the functionality of access modifiers for nested classes: | ||
+ | |||
+ | * public - the class is accessible everywhere | ||
+ | * private - the class may be accessed by any class declared in the //outer// class | ||
+ | * protected - the class may be accessed by any class up to and including the // | ||
+ | |||
+ | ===== Private Classes ===== | ||
+ | |||
+ | The following example shows how to blackbox some of your functionality in a private nested class: | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /* | ||
+ | * \foo | ||
+ | * @package \foo | ||
+ | */ | ||
+ | class foo | ||
+ | { | ||
+ | /* | ||
+ | * \foo\bar supporting | ||
+ | * @subpackage \foo\bar | ||
+ | * @private | ||
+ | */ | ||
+ | private class bar | ||
+ | | ||
+ | | ||
+ | | ||
} | } | ||
+ | } | ||
+ | | ||
+ | /* PUBLIC API METHODS HERE */ | ||
+ | | ||
+ | public function __construct() | ||
+ | { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | var_dump(new \foo()); | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | In the example '' | ||
+ | |||
+ | Attempting: | ||
+ | |||
+ | <code php> | ||
+ | var_dump(new \foo\bar()); | ||
+ | </ | ||
+ | |||
+ | will result in | ||
+ | |||
+ | < | ||
+ | Fatal error: Cannot access private class foo\bar from an unknown scope in %s on line %d | ||
+ | </ | ||
+ | |||
+ | Private classes are very private, the following example demonstrates this: | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /* | ||
+ | * foo | ||
+ | * @package foo | ||
+ | */ | ||
+ | class foo | ||
+ | { | ||
+ | /* | ||
+ | * foo\bar supporting class for foo | ||
+ | * @subpackage foo\bar | ||
+ | * @private | ||
+ | */ | ||
+ | private class bar | ||
+ | { | ||
| | ||
- | class GzFileReader | + | |
- | | + | * \foo\bar\baz supporting |
+ | * @subpackage foo\bar\baz | ||
+ | * @private | ||
+ | */ | ||
+ | private class baz | ||
+ | | ||
+ | | ||
+ | public function __construct() | ||
| | ||
- | } | + | } |
} | } | ||
| | ||
public function __construct() { | public function __construct() { | ||
- | | + | |
- | | + | |
} | } | ||
+ | } | ||
+ | | ||
+ | /* PUBLIC API METHODS HERE */ | ||
+ | | ||
+ | public function __construct() | ||
+ | { | ||
+ | $this-> | ||
+ | $this-> | ||
} | } | ||
} | } | ||
- | namespace { | + | new \foo(); |
- | var_dump(new io\FileReader()); | + | |
- | } | + | |
?> | ?> | ||
</ | </ | ||
- | The example above will output: | + | Output: |
- | '' | + | < |
+ | Fatal error: Cannot | ||
+ | </ | ||
- | The public API in the example above is io\FileReader, | + | ===== Protecting bits of your Privates ===== |
- | The above is just an example, but this is the general use case of nested | + | The following |
- | Note that only direct access to a nested | + | <code php> |
+ | <?php | ||
+ | /* | ||
+ | * foo | ||
+ | * @package foo | ||
+ | */ | ||
+ | class foo | ||
+ | { | ||
+ | /* | ||
+ | * foo\bar supporting | ||
+ | * @subpackage foo\bar | ||
+ | * @private | ||
+ | */ | ||
+ | private class bar | ||
+ | { | ||
+ | |||
+ | /* | ||
+ | * \foo\bar\baz supporting class for foo\bar | ||
+ | * @subpackage foo\bar\baz | ||
+ | * @protected | ||
+ | */ | ||
+ | protected class baz | ||
+ | { | ||
+ | |||
+ | public function __construct() { | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | public function __construct() { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /* PUBLIC API METHODS HERE */ | ||
+ | |||
+ | public function __construct() | ||
+ | { | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
- | Before you make up your mind, look at the patch, as I mentioned this is the **simplest** version of nesting that is useful, the patch is very simple indeed. | + | var_dump(new \foo()); |
+ | </ | ||
+ | |||
+ | Output: | ||
+ | |||
+ | < | ||
+ | object(foo)# | ||
+ | [" | ||
+ | object(foo\bar)# | ||
+ | [" | ||
+ | object(foo\bar\baz)# | ||
+ | } | ||
+ | } | ||
+ | [" | ||
+ | object(foo\bar\baz)# | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | The protected class '' | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
Line 82: | Line 233: | ||
Such an update should not cause any real inconvenience. | Such an update should not cause any real inconvenience. | ||
- | ===== Open Issues ===== | + | Reflection requires patching to be able to report information about outer classes and access levels. |
- | Is this the right route to take, should we consider it at all, should we pursue more complex support of nested classes. | + | ===== Open Issues ===== |
- | By more complex I mean; the use and enforcement of private/ | + | Access to private |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== | ||
Line 94: | Line 245: | ||
===== Implementation ===== | ===== Implementation ===== | ||
- | [[https:// | + | [[https:// |
]] | ]] | ||
rfc/nested_classes.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1