38 \ August 2019 \ http://www.phparch.com
Generated Singletons
Internal Apparatus
No Return Type
Listing 2, class CarleyStatePark, is identical to Listing 1
except that getInstance() does not specify a return type.
Does the generated code change? Yes, it does. The getIn-
stance() return sequence is shorter. We don’t see the
VERIFY_RETURN_TYPE V6 instruction. Now we know how, or at
least where, the PHP virtual machine implements the func-
tion/method return type. The VERIFY_RETURN_TYPE instruction
handles that task.
Here is the fragment of generated code for CarleyStatePark.
It returns self::$instance as before, but does not check the
return type:
L12 (17): EXT_STMT
L13 (17): V6 = FETCH_STATIC_PROP_R string("instance") (self)
(exception)
L14 (17): RETURN V6
Remove Duplication
We now have two nearly-identical classes, CamdenState-
Park and CarleyStatePark. Let’s remove code duplication by
creating a parent class. CamdenStatePark and CarleyStatePark
will extend that parent class. This is a mistake, but we don’t
know that yet, so let’s keep going! See Listing 3.
Here are the modified child classes, Listing 4 and Listing 5.
We added require_once 'StatePark.php'; so the code gener-
ator can find the parent class. Note that we add the @method
annotation to each child class, so our editor can help us keep
the object types correct (see line 8 of Listing 4 and Listing 5).
Listing 3. Class StatePark
- <?php
- declare(strict_types=1);
- namespace App\GeneratedSingleton;
- abstract class StatePark {
- /* @var StatePark /
- private static $instance;
- private function __construct() {
- }
- public static function getInstance(): self {
- if (!self::$instance) {
- self::$instance = new static;
- }
- return self::$instance;
- }
- }
Listing 4. Modified class CamdenStatePark
- <?php
- declare(strict_types=1);
- namespace App\GeneratedSingleton;
- require_once 'StatePark.php';
- /**
- @method static getInstance() : CamdenStatePark
- */
- class CamdenStatePark extends StatePark {
- }
Listing 5. Modified class CarleyStatePark
- <?php
- declare(strict_types=1);
- namespace App\GeneratedSingleton;
- require_once 'StatePark.php';
- /**
- @method static getInstance() : CarleyStatePark
- */
- class CarleyStatePark extends StatePark {
- }
Listing 2. Class CarleyStatePark
- <?php
- declare(strict_types=1);
- namespace App\GeneratedSingleton;
- class CarleyStatePark {
- /* @var CarleyStatePark /
- private static $instance;
- private function __construct() {
- }
- public static function getInstance() {
- if (!self::$instance) {
- self::$instance = new self;
- }
- return self::$instance;
- }
- }