duanlei2458 2016-08-11 17:45
浏览 53

难以在psysh中实例化类

I am having difficulty getting psysh to instantiate classes.

I am trying to use PSR-4 namespaces, and have registered a psr-4 autoload in composer like this:

"autoload": {
        "psr-4": {
            "System\\": "phpclasses/"
        }
    },

There is a class in phpclasses\Test.php, class name Test with a static method called hello().

I open a command shell, start psysh, and psysh appears to be working normally.

If I try to run Test::hello(); it will fail, unless I call it like this first: echo System\Test::hello();

This actually fails with the message:

PHP Fatal error: Class 'System\Test' not found in eval()'d code on line 1

but then I can successfully run: echo Test::hello();

echo System\Test::hello(); will never work

I tried Use System; and use System\Test; has no beneficial effect.

Every class I use, I have to go through this routine, which is kind of a drag because some of the classes uses static methods, and each of those will only work if each class has gone through that fail first routine.

Basically the same technique must be used for static or non-static methods.

I am running psysh in a command shell in windows 10, xampp (php 5.6), composer (current) installed.

Any suggestions for what I am doing wrong or need to do differently?

  • 写回答

1条回答 默认 最新

  • dongqiu8375 2016-08-11 21:31
    关注

    The trouble here is that you're not following PSR-4. With the config you provided, it's expecting to find classes in the System namespace inside your phpclasses folder. So, for example, the file Test.php would have the class System\Test.

    To just fix it, either change the prefix in your autoload settings to "", or add namespace System; to your Test.php file. If you want to understand why it's acting like it is, you have to understand a bit about how autoloading works in PHP:

    PHP lets you register an autoloader to find classes which haven't been encountered yet. The autoloader is handed a class name, and given a chance to find it. Usually they work by mapping class names to files in some way. When they're asked for an unknown class, they translate the class name to a file name, and try to require the file.

    PSR-4 is a standard for setting up such an autoloader, and Composer comes with a PSR-4 compliant autoloader for free. For it to work right, you have to lay out your classes and namespaces like PSR-4 expects. If you don't, you can run into strange issues like you're encountering.

    When you first tried calling Test::hello(), the class wasn't defined. Your PSR-4 autoloader translated that to a file name, but per your config, there's nowhere defined for non-namespaced classes to live, so it couldn't find a file to load, and it ended up loading nothing. After the autoloader had a chance, PHP still didn't know about that class, so it threw an error.

    When you tried calling System\Test::hello(), your PSR-4 autoloader looked it up in the config and translated it to a filename (phpclasses/Test.php), which did exist this time, so it loaded that file. PHP then tried calling the method, but it didn't know about that class, so it threw an error.

    The third time, it had already loaded your file and discovered the non-namespaced Test class. So when you tried calling it again, it didn't even bother with the autoloader, and just executed your method.

    评论

报告相同问题?

悬赏问题

  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误