Browse Source

Added autoload_except() to avoid fatals with PSR0/4 autoloaders.

Frederic G. MARAND 10 years ago
parent
commit
cc9313e1b4
4 changed files with 97 additions and 0 deletions
  1. 10 0
      .gitignore
  2. 16 0
      apps/autoload_magic.php
  3. 36 0
      misc/attributes.php
  4. 35 0
      misc/psr0.php

+ 10 - 0
.gitignore

@@ -2,3 +2,13 @@
 .buildpath
 .project
 .settings
+
+# PhpStorm project files
+.idea
+
+# PHP error logs
+php_error*
+
+# Library components
+OSInet
+

+ 16 - 0
apps/autoload_magic.php

@@ -0,0 +1,16 @@
+<?php
+/**
+ * Demonstrate using autoload_except() to avoid fatals with PSR0/4 autoloaders.
+ */
+
+require __DIR__ . '/../misc/psr0.php';
+
+spl_autoload_register('autoload_except');
+
+try {
+  $x = new Zoo();
+}
+catch (Exception $e) {
+  echo "We did not get a fatal when instantiating a nonexistent class.\n";
+  die($e->getMessage() . PHP_EOL);
+}

+ 36 - 0
misc/attributes.php

@@ -0,0 +1,36 @@
+<?php
+class Foo {
+  private static $hash;
+
+  protected static function ensure_hash() {
+    if (!isset(self::$hash)) {
+      self::$hash = spl_object_hash(self);
+      echo "Set hash to " . print_r(self::$hash, TRUE) . "\n";
+    }
+  }
+
+  protected static function ensure_key($name) {
+    $key = self::hash . '_' . $name;
+    if (!property_exists(__CLASS__, $key)) {
+      self::${$key} = NULL;
+    }
+  }
+
+  public static function attr_reader() {
+    $args = func_get_args();
+    if (!empty($args)) {
+      self::ensure_hash();
+      foreach ($args as $name) {
+        self::ensure_key($name);
+      }
+    }
+  }
+
+  public function attr_writer() {
+
+  }
+
+  public function attr_accessor() {
+
+  }
+}

+ 35 - 0
misc/psr0.php

@@ -1,4 +1,7 @@
 <?php
+
+error_reporting(-1);
+
 /**
  * Sample PSR-0 autoloader.
  *
@@ -29,3 +32,35 @@ function psr0_autoload($className) {
   $sts = @include $fileName;
   return $sts;
 }
+
+/**
+ * An SPL autoloader function designed to avoid fatals on unfound classes.
+ *
+ * Add at the end of the autoloader chain and it will implement a stub class
+ * which will throw an exception, hence be catchable, when instantiated or used
+ * in a static call, instead of causing a PHP fatal error.
+ *
+ * Note that this has nothing to do with PSR0/PSR4, and PSR4 actually forbids
+ * compliant autoloated from throwing exceptions, so a function like this is
+ * actually needed when using a PSR4 autoloader, since the autoloated itself
+ * will not be allowed to catch the missing class.
+ *
+ * @param $name
+ *   The name of a class to be loaded.
+ */
+function autoload_except($name) {
+  $src = <<<EOT
+class $name {
+  public function __construct() {
+    throw new InvalidArgumentException("$name could not be found.");
+  }
+
+  public static function __callStatic(\$method_name, \$arguments) {
+    throw new InvalidArgumentException("$name could not be found.");
+  }
+}
+
+EOT;
+
+  eval($src);
+}