What's the point of the difference between the implement of composer PSR-4 autoload and the example in PSR-4 document










1














This is the implementation of composer PSR-4 autoload:



private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;

$first = $class[0];

if (isset($this->prefixLengthsPsr4[$first]))
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\'))
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\';
if (isset($this->prefixDirsPsr4[$search]))
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir)
if (file_exists($file = $dir . $pathEnd))
return $file;







And this is the example from PSR-4 document:



protected function loadMappedFile($prefix, $relative_class)

// are there any base directories for this namespace prefix?
if (isset($this->prefixes[$prefix]) === false)
return false;


// look through base directories for this namespace prefix
foreach ($this->prefixes[$prefix] as $base_dir)

// replace the namespace prefix with the base directory,
// replace namespace separators with directory separators
// in the relative class name, append with .php
$file = $base_dir
. str_replace('\', '/', $relative_class)
. '.php';

// if the mapped file exists, require it
if ($this->requireFile($file))
// yes, we're done
return $file;



// never found it
return false;



You will find that the implementation from Composer has an additional judgement, namely:



if (isset($this->prefixLengthsPsr4[$first])) 
// ...



I can't understand why should add the judgement. Can someone tell me?










share|improve this question




























    1














    This is the implementation of composer PSR-4 autoload:



    private function findFileWithExtension($class, $ext)
    {
    // PSR-4 lookup
    $logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;

    $first = $class[0];

    if (isset($this->prefixLengthsPsr4[$first]))
    $subPath = $class;
    while (false !== $lastPos = strrpos($subPath, '\'))
    $subPath = substr($subPath, 0, $lastPos);
    $search = $subPath . '\';
    if (isset($this->prefixDirsPsr4[$search]))
    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
    foreach ($this->prefixDirsPsr4[$search] as $dir)
    if (file_exists($file = $dir . $pathEnd))
    return $file;







    And this is the example from PSR-4 document:



    protected function loadMappedFile($prefix, $relative_class)

    // are there any base directories for this namespace prefix?
    if (isset($this->prefixes[$prefix]) === false)
    return false;


    // look through base directories for this namespace prefix
    foreach ($this->prefixes[$prefix] as $base_dir)

    // replace the namespace prefix with the base directory,
    // replace namespace separators with directory separators
    // in the relative class name, append with .php
    $file = $base_dir
    . str_replace('\', '/', $relative_class)
    . '.php';

    // if the mapped file exists, require it
    if ($this->requireFile($file))
    // yes, we're done
    return $file;



    // never found it
    return false;



    You will find that the implementation from Composer has an additional judgement, namely:



    if (isset($this->prefixLengthsPsr4[$first])) 
    // ...



    I can't understand why should add the judgement. Can someone tell me?










    share|improve this question


























      1












      1








      1







      This is the implementation of composer PSR-4 autoload:



      private function findFileWithExtension($class, $ext)
      {
      // PSR-4 lookup
      $logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;

      $first = $class[0];

      if (isset($this->prefixLengthsPsr4[$first]))
      $subPath = $class;
      while (false !== $lastPos = strrpos($subPath, '\'))
      $subPath = substr($subPath, 0, $lastPos);
      $search = $subPath . '\';
      if (isset($this->prefixDirsPsr4[$search]))
      $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
      foreach ($this->prefixDirsPsr4[$search] as $dir)
      if (file_exists($file = $dir . $pathEnd))
      return $file;







      And this is the example from PSR-4 document:



      protected function loadMappedFile($prefix, $relative_class)

      // are there any base directories for this namespace prefix?
      if (isset($this->prefixes[$prefix]) === false)
      return false;


      // look through base directories for this namespace prefix
      foreach ($this->prefixes[$prefix] as $base_dir)

      // replace the namespace prefix with the base directory,
      // replace namespace separators with directory separators
      // in the relative class name, append with .php
      $file = $base_dir
      . str_replace('\', '/', $relative_class)
      . '.php';

      // if the mapped file exists, require it
      if ($this->requireFile($file))
      // yes, we're done
      return $file;



      // never found it
      return false;



      You will find that the implementation from Composer has an additional judgement, namely:



      if (isset($this->prefixLengthsPsr4[$first])) 
      // ...



      I can't understand why should add the judgement. Can someone tell me?










      share|improve this question















      This is the implementation of composer PSR-4 autoload:



      private function findFileWithExtension($class, $ext)
      {
      // PSR-4 lookup
      $logicalPathPsr4 = strtr($class, '\', DIRECTORY_SEPARATOR) . $ext;

      $first = $class[0];

      if (isset($this->prefixLengthsPsr4[$first]))
      $subPath = $class;
      while (false !== $lastPos = strrpos($subPath, '\'))
      $subPath = substr($subPath, 0, $lastPos);
      $search = $subPath . '\';
      if (isset($this->prefixDirsPsr4[$search]))
      $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
      foreach ($this->prefixDirsPsr4[$search] as $dir)
      if (file_exists($file = $dir . $pathEnd))
      return $file;







      And this is the example from PSR-4 document:



      protected function loadMappedFile($prefix, $relative_class)

      // are there any base directories for this namespace prefix?
      if (isset($this->prefixes[$prefix]) === false)
      return false;


      // look through base directories for this namespace prefix
      foreach ($this->prefixes[$prefix] as $base_dir)

      // replace the namespace prefix with the base directory,
      // replace namespace separators with directory separators
      // in the relative class name, append with .php
      $file = $base_dir
      . str_replace('\', '/', $relative_class)
      . '.php';

      // if the mapped file exists, require it
      if ($this->requireFile($file))
      // yes, we're done
      return $file;



      // never found it
      return false;



      You will find that the implementation from Composer has an additional judgement, namely:



      if (isset($this->prefixLengthsPsr4[$first])) 
      // ...



      I can't understand why should add the judgement. Can someone tell me?







      composer-php psr-4






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 '18 at 21:47









      rob006

      9,1543932




      9,1543932










      asked Sep 6 '18 at 10:26









      qq412445773

      62




      62






















          1 Answer
          1






          active

          oldest

          votes


















          0














          First, these two functions are taken out of context and do quite different things - even if you compare function parameters you can see that they do not correspond to each other, so comparing them does not make much sense.



          But this additional condition in Composer's implementation ensures that more precise namespace takes precedence over more general definition. Because in general packages often share the same root namespace. For example in Yii 2 Framework:




          • yii2 package with core framework uses yii as root namespace for all classes, and source code is located in vendor/yiisoft/yii2.


          • yii2-redis extension uses yiiredis namespace, and source code is located in vendor/yiisoft/yii2-redis.

          In this case if you want to resolve file with yiiredisConnection class definiton you have two options:




          1. vendor/yiisoft/yii2/redis/Connection,


          2. vendor/yiisoft/yii2-redis/Connection.

          The second one is correct. And thanks to this additional condition in Composer's implementation it will be used as first choice, since definition for yiiredis namespace is more precise as for yii namespace. In this way you can increase performance of autoloader (however it is irrelevant if you're using optimized autoloader), make it more predictable and allows you to override some classes (you just need to use more precise namespace for file with new implementation).






          share|improve this answer




















          • thanks very much.And I'll read your answer more times for a better understanding.
            – qq412445773
            Dec 18 '18 at 12:51










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52201975%2fwhats-the-point-of-the-difference-between-the-implement-of-composer-psr-4-autol%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          First, these two functions are taken out of context and do quite different things - even if you compare function parameters you can see that they do not correspond to each other, so comparing them does not make much sense.



          But this additional condition in Composer's implementation ensures that more precise namespace takes precedence over more general definition. Because in general packages often share the same root namespace. For example in Yii 2 Framework:




          • yii2 package with core framework uses yii as root namespace for all classes, and source code is located in vendor/yiisoft/yii2.


          • yii2-redis extension uses yiiredis namespace, and source code is located in vendor/yiisoft/yii2-redis.

          In this case if you want to resolve file with yiiredisConnection class definiton you have two options:




          1. vendor/yiisoft/yii2/redis/Connection,


          2. vendor/yiisoft/yii2-redis/Connection.

          The second one is correct. And thanks to this additional condition in Composer's implementation it will be used as first choice, since definition for yiiredis namespace is more precise as for yii namespace. In this way you can increase performance of autoloader (however it is irrelevant if you're using optimized autoloader), make it more predictable and allows you to override some classes (you just need to use more precise namespace for file with new implementation).






          share|improve this answer




















          • thanks very much.And I'll read your answer more times for a better understanding.
            – qq412445773
            Dec 18 '18 at 12:51















          0














          First, these two functions are taken out of context and do quite different things - even if you compare function parameters you can see that they do not correspond to each other, so comparing them does not make much sense.



          But this additional condition in Composer's implementation ensures that more precise namespace takes precedence over more general definition. Because in general packages often share the same root namespace. For example in Yii 2 Framework:




          • yii2 package with core framework uses yii as root namespace for all classes, and source code is located in vendor/yiisoft/yii2.


          • yii2-redis extension uses yiiredis namespace, and source code is located in vendor/yiisoft/yii2-redis.

          In this case if you want to resolve file with yiiredisConnection class definiton you have two options:




          1. vendor/yiisoft/yii2/redis/Connection,


          2. vendor/yiisoft/yii2-redis/Connection.

          The second one is correct. And thanks to this additional condition in Composer's implementation it will be used as first choice, since definition for yiiredis namespace is more precise as for yii namespace. In this way you can increase performance of autoloader (however it is irrelevant if you're using optimized autoloader), make it more predictable and allows you to override some classes (you just need to use more precise namespace for file with new implementation).






          share|improve this answer




















          • thanks very much.And I'll read your answer more times for a better understanding.
            – qq412445773
            Dec 18 '18 at 12:51













          0












          0








          0






          First, these two functions are taken out of context and do quite different things - even if you compare function parameters you can see that they do not correspond to each other, so comparing them does not make much sense.



          But this additional condition in Composer's implementation ensures that more precise namespace takes precedence over more general definition. Because in general packages often share the same root namespace. For example in Yii 2 Framework:




          • yii2 package with core framework uses yii as root namespace for all classes, and source code is located in vendor/yiisoft/yii2.


          • yii2-redis extension uses yiiredis namespace, and source code is located in vendor/yiisoft/yii2-redis.

          In this case if you want to resolve file with yiiredisConnection class definiton you have two options:




          1. vendor/yiisoft/yii2/redis/Connection,


          2. vendor/yiisoft/yii2-redis/Connection.

          The second one is correct. And thanks to this additional condition in Composer's implementation it will be used as first choice, since definition for yiiredis namespace is more precise as for yii namespace. In this way you can increase performance of autoloader (however it is irrelevant if you're using optimized autoloader), make it more predictable and allows you to override some classes (you just need to use more precise namespace for file with new implementation).






          share|improve this answer












          First, these two functions are taken out of context and do quite different things - even if you compare function parameters you can see that they do not correspond to each other, so comparing them does not make much sense.



          But this additional condition in Composer's implementation ensures that more precise namespace takes precedence over more general definition. Because in general packages often share the same root namespace. For example in Yii 2 Framework:




          • yii2 package with core framework uses yii as root namespace for all classes, and source code is located in vendor/yiisoft/yii2.


          • yii2-redis extension uses yiiredis namespace, and source code is located in vendor/yiisoft/yii2-redis.

          In this case if you want to resolve file with yiiredisConnection class definiton you have two options:




          1. vendor/yiisoft/yii2/redis/Connection,


          2. vendor/yiisoft/yii2-redis/Connection.

          The second one is correct. And thanks to this additional condition in Composer's implementation it will be used as first choice, since definition for yiiredis namespace is more precise as for yii namespace. In this way you can increase performance of autoloader (however it is irrelevant if you're using optimized autoloader), make it more predictable and allows you to override some classes (you just need to use more precise namespace for file with new implementation).







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 '18 at 22:03









          rob006

          9,1543932




          9,1543932











          • thanks very much.And I'll read your answer more times for a better understanding.
            – qq412445773
            Dec 18 '18 at 12:51
















          • thanks very much.And I'll read your answer more times for a better understanding.
            – qq412445773
            Dec 18 '18 at 12:51















          thanks very much.And I'll read your answer more times for a better understanding.
          – qq412445773
          Dec 18 '18 at 12:51




          thanks very much.And I'll read your answer more times for a better understanding.
          – qq412445773
          Dec 18 '18 at 12:51

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52201975%2fwhats-the-point-of-the-difference-between-the-implement-of-composer-psr-4-autol%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3

          Museum of Modern and Contemporary Art of Trento and Rovereto