这是init.php
文件所需的我的index.php
文件:
<?php
/**
*
* Initialization file: Will require all components we need.
*
**/
/* Set session */
session_start(); // Start session
/* Helpers */
require_once 'helpers/Sanitize.php'; // Sanatizing (escaping) strings
require_once 'helpers/Token.php'; // Generate tokens
require_once 'helpers/Hash.php'; // Hash class
require_once 'helpers/Input.php'; // Inputs manipulations
require_once 'helpers/Validation.php'; // Validation class
require_once 'helpers/Redirect.php'; // Redirect helper
require_once 'helpers/Session.php'; // Session manipulations
require_once 'helpers/Cookie.php'; // Cookies manipulations
/* Core */
require_once 'core/Config.php'; // Default global vairables
require_once 'core/App.php'; // Load App class from CORE
require_once 'core/Controller.php'; // Load Controller class from CORE
require_once 'core/Database.php'; // Load Database class
/* Models */
require_once '/www/myapp/models/System_user.model.php'; // System User Model
require_once '/www/myapp/models/user/User.model.php'; // User Model
require_once '/www/myapp/models/exec/something_usage.model.php'; // something model
require_once '/www/myapp/models/abc/abc.model.php'; // A class for handling trees
require_once '/www/myapp/models/Group.model.php'; // Group Model
require_once '/www/myapp/models/banana.model.php'; // A class for handling trees
// require_once '/www/myapp/models/Tree_db.php'; // A class for handling trees
如您所见,我正在重新获取我的所有class文件,这是一种不好的做法。 经过小型研究,我发现有一个函数可以在每次调用时自动加载类:
// /* Autoload classes from directory */
// spl_autoload_register(function($class) {
// require_once 'classes/' . $class . '.php'; // No such directory
// });
我无法使用它,因为我的课程不在一个文件夹中,也不容易导航到。
我继续研究,found out I can use a composer command composer dump-autoload -o
可能需要我的代码,方法是在每个类的顶部声明namespaces
(遵循文件夹结构),并在使用时声明use
一个特定的类,并且需要autoload.php
而不是上面提到的列表:
/* Composer */
require_once '../vendor/autoload.php'; // Loading composer components
我将此更改应用于我的所有类-控制器类文件,模型类文件(和子文件夹类文件),核心类和数据库类。
示例:
拥有文件夹/www/app/models/system_users.model.php
我添加了命名空间App\Models;
(并且类名是System_users
),如果该类对象在其他类中实例化,则在文件顶部使用use App\Modal\System_uses;
。
但是我不断收到此错误消息:
[22-Oct-2018 12:27:31] PHP Fatal error: Uncaught Error: Class 'Config' not found in /www/app/views/login/pages-login.php:14
Stack trace:
#0 /www/app/core/Controller.php(51): require_once()
#1 /www/app/controllers/login.php(27): app\Core\Controller->view('login/pages-log...')
#2 [internal function]: app\Controllers\Login->index()
#3 /www/app/core/App.php(51): call_user_func_array(Array, Array)
#4 /www/public/index.php(15): app\Core\App->__construct()
#5 {main}
thrown in /www/app/views/login/pages-login.php on line 14
[22-Oct-2018 12:27:31] PHP Fatal error: Class 'Controller' not found in /www/app/controllers/Error_404.php on line 7
[22-Oct-2018 12:27:31] PHP Stack trace:
[22-Oct-2018 12:27:31] PHP 1. {main}() /www/public/index.php:0
[22-Oct-2018 12:27:31] PHP 2. app\Core\App->__construct() /www/public/index.php:15
[22-Oct-2018 12:27:31] PHP 3. require_once() /www/app/core/App.php:31
可能是因为我不需要视图中的Config
类。但是直到现在,使用requre once
都可以正常工作,我真的发现在每个视图顶部都使用use App\Core\Config;
会很麻烦。
如何使用名称空间处理这种情况的正确方法?
编辑:
我正在添加我的代码结构:
/www/public/index.php
<?php
use MyApp\Core\App;
/**
*
* Index: First page a user visits.
*
**/
# Reuiring init.php: Responsible for initializing classes we want to use.
require_once '../myapp/init.php';
# Initialize App class
$app = new App();
/www/myapp/core/controller.php
<?php
namespace MyApp\Core;
use MyApp\Models\System_user;
use MyApp\Core\Config;
/**
*
* Controller instance:
*
*/
class Controller
{
/*=================================
= Variables =
=================================*/
# System User
protected $system_user;
/*===============================
= Methods =
================================*/
/**
*
* Model Class: Loads a requested model
* @param $model String Gets a model name
*
*/
protected function model($model)
{
require_once '../myapp/models/' . $model . '.php';
return new $model();
}
/**
*
* View Class: Loads a requested view
* @param $view String Gets a view name
* @param $data Array (optional) Gets an array of variables to pass to the view
* @throws Plain view
*
*/
protected function view($view, $data=[])
{
require_once '../myapp/views/' . $view . '.php';
}
/**
*
* Check if a user is logged in
*
*/
protected function is_loggedin()
{
...
}
/www/myapp/core/app.php
<?php
namespace MyApp\Core;
// use MyApp\Core\Controller;
use MyApp\Controllers;
/**
*
* App instance: Handles controlles (specifically gets routs data)
*
*/
class App
{
protected $controller = 'Error_404';
protected $method = 'index';
protected $parameters = array();
protected $contollerNamespace;
public function __construct()
{
# Get parsed URL
$url = $this->parseUrl();
# Check if contorller via input-url exists in the controller folder
if (file_exists('../myapp/controllers/' . $url[0] . '.php')){
$this->controller = $url[0]; // Replace current 'home' controller with the new one
$this->contollerNamespace = 'MyApp\\Controllers\\'.$url[0];
unset($url[0]); // Remove controller name from the array.
}
# Require the controllers class via controllers folder
require_once '../myapp/controllers/' . $this->controller . '.php';
# Create a new obect of the controller (by its name)
$this->controller = new $this->contollerNamespace; // ex: new Home() -- or: new Login()
# Chech if method is passed
if ( isset($url[1]) ) {
# Check if method exists in class
if ( method_exists($this->controller, $url[1]) ) {
# Set new method variable
$this->method = $url[1];
unset($url[1]);
}
}
# Set parameters (if any).
$this->parameters = $url ? array_values($url) : [];
# Summon controller with the relevant method and variables.
call_user_func_array([$this->controller, $this->method], $this->parameters);
}
/**
*
* Parses the url - Gets the $_GET input via .htaccess definition.
*
*/
public function parseUrl()
{
if ( isset($_GET['url']) ) {
return $url = explode('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL));
}
}
}
/www/myapp/controllers/login.php
<?php
namespace MyApp\Controllers;
use MyApp\Core\Controller;
use MyApp\Models\System_user;
use MyApp\Core\Config;
/**
* Login Class
*/
class Login extends Controller
{
/**
*
* Login Main login Form
*
*/
public function index($name ='')
{
// Create a new system user
$system_user = new System_user();
// If user is logged in - Redirect to dashboard
if ( $system_user->check_logged_in() )
Redirect::to('dashboard'); // Redirect to login form
else
$this->view('login/pages-login'); // Redirect to login form
}
/**
*
* User login: Creates the user login.
*
*/
public function user_login()
{
...
}
}
答案 0 :(得分:1)
Composer在PSR-4自动加载标准上运行。
https://www.php-fig.org/psr/psr-4/
在您的composer.json
中,为您的类添加一个自动加载器名称空间。例如,在我的表单包中,它看起来像这样:
"autoload": {
"psr-4": {
"Del\\Form\\": "src/",
"DelTesting\\Form\\": "tests/unit/Del/Form/"
}
},
这是什么意思?基本上src/
中的所有类都将具有命名空间Del\Form
。
例如,src/Form.php
看起来像这样:
<?php
namespace Del\Form;
class Form
{
// code
}
请注意,类名应与文件名匹配,即类Form
应称为Form.php
。
现在,如果您在src
中创建文件夹,则这些文件夹将被添加到命名空间中。另一个示例,src/Field/Text.php
如下所示:
<?php
namespace Del\Form\Field;
class Text
{
// code
}
如果遵守这些约定,所有内容都会自动加载。
在编辑composer.json
以添加名称空间之后,运行composer dumpautoload
来生成作曲家使用的类映射。