PSR4自动加载器不会从类中自动加载
当我在index.php
中使用它时,自动加载器起作用,但是当我在index.php
中创建一个对象时,此对象必须创建其他对象(这些对象都在相同的名称空间),它抛出了错误未被发现的错误:(...)
中找不到类'xxx'。
我的composer.json
看起来像这样:
{
"autoload": {
"psr-4": {
"pizzaCase\\": "src",
"Connection\\": "src/Connection/",
"Elements\\": "src/Elements/"
}
},
"require": {
"cboden/ratchet": "^0.4"
}
}
我的index.php
看起来像这样:
<?php
require_once __DIR__. '/vendor/autoload.php';
require_once __DIR__."/src/config.php";
use Connection\Database;
use Elements\Form;
use Elements\FormElement;
use Elements\FormElementRadio;
// Database::init();
$form = new Form();
$data["options"] = "soemthing, something else";
$form->addElement("", "pizza", "", "Choose pizza", "radio", $data);
?>
在addelement
方法中,我创建了一个也在内部的对象src/Elements/
名称空间,但它抛出了上面提到的错误。
我的addElement
方法的主体看起来像这样:
<?php
namespace Elements;
class Form
{
public static $leftSize = 3;
protected $elements = [];
public function addElement($table, $name, $value, $label=false, $type = false, $data = false)
{
$type = ucfirst($type);
$class = "FormElement{$type}";
//FAILS HERE
if(class_exists($class))
{
//CLASS EXISTS, CREATE OBJECT FROM RESPECTIVE CLASS
$form = new $class($table, $name, $value, $label, $type, $data);
$this->elements[$name] = $form;
}
}
}
我在做什么错(或丢失)?如何从index.php启用自动加载器可以自动加载它,但是我创建的对象不能在没有自动加载器失败的情况下创建其他对象?
The autoloader works when I use it in index.php
, but when I create an object within index.php
and this object has to create other objects (which are all in the same namespace), it throws the error Uncaught Error: Class 'xxx' not found in (...)
.
My composer.json
looks like this:
{
"autoload": {
"psr-4": {
"pizzaCase\\": "src",
"Connection\\": "src/Connection/",
"Elements\\": "src/Elements/"
}
},
"require": {
"cboden/ratchet": "^0.4"
}
}
My index.php
looks like this:
<?php
require_once __DIR__. '/vendor/autoload.php';
require_once __DIR__."/src/config.php";
use Connection\Database;
use Elements\Form;
use Elements\FormElement;
use Elements\FormElementRadio;
// Database::init();
$form = new Form();
$data["options"] = "soemthing, something else";
$form->addElement("", "pizza", "", "Choose pizza", "radio", $data);
?>
In the addElement
method I then create an object which is also within the src/Elements/
namespace, but it throws the error mentioned above.
The body of my addElement
method looks like this:
<?php
namespace Elements;
class Form
{
public static $leftSize = 3;
protected $elements = [];
public function addElement($table, $name, $value, $label=false, $type = false, $data = false)
{
$type = ucfirst($type);
$class = "FormElement{$type}";
//FAILS HERE
if(class_exists($class))
{
//CLASS EXISTS, CREATE OBJECT FROM RESPECTIVE CLASS
$form = new $class($table, $name, $value, $label, $type, $data);
$this->elements[$name] = $form;
}
}
}
What am I doing wrong (or missing)? How come the autoloader can autoload it from index.php, but the object I create cannot create other objects without autoloader failing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
区别不与代码运行的位置有关。不同之处在于,失败的代码正在尝试选择要动态加载的类。
在PHP中,命名空间本质上是一个编译时间功能:在运行任何代码之前,编译器将查看所有不以
\
开头的类名的引用命名空间,或根据您指定的规则使用
语句。当代码运行时,当前名称空间和使用语句根本看不到。当您动态地指定类名时,编译器只是看到一个字符串,而不是类名称,因此单独将其留下。然后,当代码运行时,假定的类名称已完全指定,而不是相对于当前名称空间或使用语句。
因此,解决方案很简单 - 创建动态类名称时指定全名空间:
您还可以使用魔术常数
__命名空间__
让编译器替换为您的 current 代码>使用语句):或者,如果您在之间选择了一组特定的类,则可以使用
:: class
语法在编译时生成字符串,以基于当前命名空间和任何使用
语句有效:The difference is not to do with where the code is being run; the difference is that the failing code is trying to choose which class to load dynamically.
In PHP, namespaces are essentially a compile-time feature: before any of your code is run, the compiler looks at all references to class names which don't start with
\
, and prefixes them with the current namespace, or according to rules you've specified withuse
statements. When the code runs, the current namespace, and use statements, aren't visible at all.When you specify a class name dynamically, the compiler just sees a string, not a class name, so leaves it alone. Then when the code runs, the class name looked up is assumed to be fully specified, not relative to the current namespace or use statements.
So the solution is simple - specify the full namespace when creating the dynamic class name:
You can also use the magic constant
__NAMESPACE__
to have the compiler substitute the current namespace name for you (obviously, this still won't account for anyuse
statements):Alternatively, if you have a specific set of classes you are choosing between, you can use the
::class
syntax to generate a string at compile time, based on the current namespace and anyuse
statements in effect:可能是因为您为SRC目录有多个名称空间。
您只会为SRC创建一个命名空间
通常,
It could be because you’re having multiple namespaces for the src directory.
Usually you would just create a namespace for src like this
And then just use PizzaCase\Elements and PizzaCase\Connections as namespaces