用户:Valiant

来自站长百科
跳转至: 导航、​ 搜索

TODO[ ]

Embedding and Integration[ ]

See the Embedding Development Roadmap. Next on the list are:

  • polishing and committing the embed/ module (user synchronization)

Other[ ]

GalleryCoreApi::requireOnce[ ]

  • We found out that the "10x faster" claim for our $loaded[$file] require_once wrapper cannot be reproduced
  • An interesting approach would be to just change the include_path right at the beginning in GalleryInitFirstPass and add the gallery2 directory and gallery2/plugins to the include path. Then, we could use a plain require_once instead of GalleryCoreApi::requireOnce (about 15% faster)
  • But the include_path can only be changed with ini_set (and since 4.3.0 with a dedicated function), so if we can't change the include_path successfully, we still need our GalleryCoreApi::requireOnce wrapper and this is the greatest common denominator. We need to support this case
  • So we're back to using GalleryCoreApi::requireOnce and in this function, we'd like to use require_once directly if the include_path has been changed and our old mechanism with getPluginDir etc if the include path wasn't changed
  • The "has the include path been changed" check should be as cheap as a if ($staticVar) check, since we're talking about a highly optimized function (maybe check the performance difference between GDC::containsKey)
  • A static var would be bad for testability (unless we use another parameter to set/reset this var)
  • If possible, we don't want to add an additional parameter to requireOnce to set/reset this static var
  • In GalleryInitFirstPass, we'd have to first change the include_path and then requireOnce all the files (unless we use a GDC var which we can reset)
  • don't forget about embedded G2, where we need to add the gallery2 folder to the include path and can't just replace the include_path
  • In the end, we'll have to see if the resulting function would be faster than this optimized version (since all the checks etc would render it a little slower):
 function requireOnce($file, $skipBaseDirectoryDetection=false) {
     static $loaded, $galleryBaseDir;
     if (strpos($file, '..') !== false) {
         return;
     }	
     if (!isset($loaded[$file])) {
         if ($skipBaseDirectoryDetection || !strncmp($file, 'lib', 3)) {
             if (empty($galleryBaseDir)) {
                 $galleryBaseDir = GALLERY_CONFIG_DIR . '/';
             }
             require_once($galleryBaseDir . $file);
         } else {
             if (!preg_match('/^(module|theme)s\/(.+)\/.+/iU', $file, $pluginData)) {
                 print('Invalid path: ' . $file);
                 return;
             }
             require_once(GalleryCoreApi::getPluginBaseDir($pluginData[1], $pluginData[2]) . $file);		
         }
         $loaded[$file] = 1;
     }
 }

A prototype of setting / checking include_path: In init.inc GalleryInitFirstpass:

 /* Add the plugins dir to the include path */
 $includePath = @ini_get('include_path');
 if (substr($includePath, -1) != PATH_SEPARATOR) {
   $includePath .= PATH_SEPARATOR;
 }
 $includePath .= GALLERY_CONFIG_DIR . PATH_SEPARATOR .
 GALLERY_CONFIG_DIR . DIRECTORY_SEPARATOR . 'plugins';
 @ini_set('include_path', $includePath);

In requireOnce before the if (isset($loaded[$file])) { check:

 if (!empty($includePathChanged)) {
   return require_once($file);
 } else if (!isset($includePathChanged)) {
   global $gallery;
   if (strpos(@ini_get('include_path'),
                       PATH_SEPARATOR . GALLERY_CONFIG_DIR === false)) {
     $includePathChanged = false;
   } else {
     $includePathChanged = true;
   }
 }

Issues:

  • static var -> can't test both cases
  • performance not yet compared with optimized requireOnce and pure require_once, but the improvement would be very small anyway

Bottom line:

  • The approach with changing include_path would have been very elegant and the performance would have been improved (by maybe 50 micro seconds * nr of files includes per request)
  • But since we must deal with hosts that can't change the include_path during runtime, we can't call require_once directly and we need to check on each require_once call whether to use require_once directly or our low-tech method. We will see if it's worth it.
  • see http://gallery.pastebin.com/459591