ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
这一章是最高级也是最重要的教程,但是本人不要求你马上看明白,因为你们是初学者,等你们全学会了,再回来看,就明白很多了,里面很多内容都是初学都不能乱修改的,所以我建议初学者看看知道有这么一回事就行了,因为里面配置内容很多在多个章里面都有介绍说明的。 # 配置 系统容器是一个DI容器,包含应用程序运行所需的所有服务和参数。 很快你就能够: 1、创建系统容器 2、使用NEON文件配置应用程序 3、处理生产和开发模式 4、创建和使用自己的容器扩展 系统容器是一个静态依赖注入容器,它保存应用程序需要的所有服务和参数。 这意味着不仅是框架本身的服务,而是你决定使用的每个库的服务。 看看这样的系统容器的例子。 开发人员了解到,编写容器是一件非常乏味的工作。 随着应用程序的增长,管理应用程序肯定变得困难。 Nette会为你做的工作! 使用简单的配置语言,我们将描述应用程序的服务,框架将生成PHP代码。 在所有严重性 - 上面链接的容器也是这样生成的。 # 配置器 代码生成的任务是给Nette \ Configurator类。 编译过程只被触发一次,其结果被缓存。 为此,我们需要选择一个目录来存储这个代码。代码在bootstrap.php文件里面。 ~~~ $configurator = new Nette\Configurator; $configurator->setTempDirectory(__DIR__ . '/../temp'); ~~~ 现在我们只是添加一个路径到配置文件: ~~~ $configurator->addConfig(__DIR__ . '/config/config.neon'); ~~~ 获取容器的实例是最简单的: ~~~ // 返回SystemContainer实例 $container = $configurator->createContainer(); ~~~ 以上小节介绍bootstrap.php一些代码内容。 # 环境 配置器尝试检测应用程序是否正在生产或开发服务器上运行。 只要客户端的IP地址是127.0.0.1,服务器就会被认为是开发的。 如果我们不能找到使用哪个环境,但它不在乎,因为它只用于从配置文件加载部分。 我们可以通过addConfig()的第二个参数来定义它。 ~~~ $environment = Nette\Configurator::detectDebugMode('your ip address') ? $configurator::DEVELOPMENT : $configurator::PRODUCTION; $configurator->addConfig(__DIR__ . '/config/config.neon', $environment); ~~~ 我们可以通过$ environment传递任何字符串,不仅仅是生产或开发。 通过这个,我们可以要求Configurator加载配置文件的任何部分。 但是正确的检测取决于你(例如,通过系统变量getenv('COMPUTERNAME')或服务器的主机名$ _SERVER ['SERVER_NAME'])。 # 开发模式 有点不同的是应用程序运行模式。 我们可以作为开发人员访问生产服务器,我们希望激活Tracy调试器。 运行模式通过与上述环境相同的原理,根据客户端的IP地址区分。 我们通过isDebugMode()获取模式,并通过setDebugMode()设置模式。 当我们通过enableDebugger()启用调试器时很有用,它必须放在模式设置之后。 ~~~ // 激活列出的IP地址的Tracy调试器 $configurator->setDebugMode(['90.180.45.360', '90.180.45.361']); // 或任何人 $configurator->setDebugMode(); // = TRUE // 或没有人 $configurator->setDebugMode($configurator::NONE); // = FALSE $configurator->enableDebugger(__DIR__ . '/../log'); ~~~ # 类自动加载 要编译容器,Configurator需要加载配置文件中提到的所有类。 它是方便的自动加载在您的处置和Configurator提供一个方法创建一个RobotLoader的实例。 我们只添加希望被索引的目录并激活装载器。 不要忘记在调用createContainer()之前放置此代码。 ~~~ $configurator->createRobotLoader() ->addDirectory(__DIR__) ->register(); ~~~ # 框架配置 配置通常以NEON格式编写。 有乐趣尝试的语法在http://ne-on.org。 Nette Framework的许多功能可以在配置文件中设置。 # HTTP代理 您可以定义http代理,使HTTP请求的远程地址和远程主机正确。这文件配置在config.neon。 ~~~ http: proxy: 127.0.0.1 # ip address, range, hostname or array of these values ~~~ # Sessions 在这里你可以设置所有指令(camelCase格式)。 ~~~ session: autoStart: true # default is smart expiration: 10 days name: ... ... ~~~ autoStart:smart。 仅当会话已存在时,它才自动启动会话。 以后还会说明SESSIONS内容。 # Application ~~~ application: debugger: true # debugger bar panel catchExceptions: %productionMode% errorPresenter: Front:Error mapping: # mapping between presenter name and presenter class Front: App\*Module\*Presenter ~~~ # Routing ~~~ routing: debugger: true # debugger bar panel routes: index.php: Dashboard:default '<presenter>/<action>[/<id>]': Dashboard:default ~~~ # 安全 ~~~ security: debugger: true # debugger bar panel users: johndoe: secretpassword roles: guest: member: admin: [member] # admin extends member resources: file: ~~~ 通过填写用户选项,您创建SimpleAuthenticator,通过定义角色或资源创建Nette \ Security \ Permission授权者。 # HTTP headers ~~~ http: frames: ... # ovlivňuje hlavičku X-Frame-Options ~~~ 出于安全原因,Nette框架默认发送HTTP头X-Frame-Options:SAMEORIGIN,以便页面可以嵌入在仅来自同一域上的页面的iframe中。 这种行为在某些情况下可能是不需要的(例如,如果你正在开发一个Facebook应用程序)。 您可以通过框架覆盖此设置:yes,frames:http://allowed-host.com或frames:no。 # Mailing 默认邮件程序是SendmailMailer。 通过设置smtp,您可以激活SmtpMailer。 ~~~ mail: smtp: true # use SmtpMailer instead of SendmailMailer # optional settings host: ... port: ... username: ... password: ... secure: # possible values are ssl, tls or null timeout: ... ~~~ # Database 您可以定义多个数据库连接,如果这样做,您可以设置哪一个将自动注入您的服务通过autowired选项。 以下代码显示如何设置一个名为default的连接。 ~~~ database: default: dsn: "sqlite2:%appDir%/models/demo.db" user: ... password: ... options: [PDO::MYSQL_ATTR_COMPRESS = true] debugger: false # debugger bar panel explain: false # explain queries in debugger bar reflection: discovered # or static or classname, default is discovered autowired: true ~~~ 这将创建service @ nette.database.default并为您设置反射和缓存。 # Forms 您可以更改默认验证错误消息。 ~~~ forms: messages: EQUAL: 'Please enter %s.' FILLED: 'Please complete mandatory field.' MIN_LENGTH: 'Please enter a value of at least %d characters.' EMAIL: '%label must be valid e-mail' ~~~ # Latte 您可以打开和关闭XHTML呈现模式并注册自定义宏。 自定义宏可以作为类名称或作为服务引用传递。 默认的调用方法是install,您可以通过附加双冒号和自定义方法名称来更改它。 ~~~ latte: xhtml: yes # default is no macros: - App\MyLatteMacros::register # static method, classname or callable - @App\MyLatteMacrosFactory # service with install method - @App\MyLatteMacrosFactory::register # service with register method services: - App\MyLatteMacrosFactory ~~~ # DI container ~~~ di: debugger: true #debugger bar panel accessors: true #enables $container->serviceName shortcut ~~~ # Tracy debugger ~~~ tracy: email: webmaster@example.com # for sending error logs strictMode: TRUE editor: ... browser: ... bar: # debugger bar panels - Nette\Bridges\DITracy\ContainerPanel # alias of DI container bar - IncludePanel - XDebugHelper('myIdeKey') - MyPanel(@MyService) blueScreen: # blue screen panels - DoctrinePanel::renderException ~~~ # Low-level modifications 所有这些设置影响最终的DI容器。 与服务部分中的直接定义相比,它提供了更短和更直接的语法。 如果您需要自己调整这些服务,您可以重新定义它们: ~~~ services: mail.mailer: class: MySmtpMailer application.presenterFactory: class: MyPresenterFactory ~~~ 或创建扩展默认服务的新服务: ~~~ services: myConnection < nette.database.default: setup: $onQuery: [ @logger::log ] ~~~ # 自定义服务 **服务定义** ~~~ services: database: Nette\Database\Connection(%dsn%, %user%, %password%) # or multi-lines database: factory: Nette\Database\Connection(%dsn%, %user%, %password%) # or more multi-lines :-) database: class: Nette\Database\Connection arguments: [%dsn%, %user%, %password%] ~~~ 生成: ~~~ function createServiceDatabase() { return new Nette\Database\Connection( $this->parameters['dsn'], $this->parameters['user'], $this->parameters['password'] ); } ~~~ 服务定义: ~~~ services: database: class: Nette\Database\Connection factory: DbFactory::createConnection ~~~ DbFactory::createConnection: ~~~ class DbFactory { static function createConnection(Nette\DI\Container $container) { ... } } ~~~ Generates: ~~~ function createServiceDatabase() { return DbFactory::createConnection($this); } ~~~ # Setup ~~~ services: database: class: Nette\Database\Connection(%dsn%, %user%, %password%) setup: - setCacheStorage(@cacheStorage) ~~~ Generates: ~~~ function createServiceDatabase() { $service = new Nette\Database\Connection(...); $service->setCacheStorage($this->cacheStorage); return $service; } ~~~ 自动装配功能自动添加依赖项,因此甚至不必提及它们: ~~~ setup: - setCacheStorage ~~~ 在cacheStorage服务不存在的情况下,可以使用调用的结果作为参数: ~~~ setup: - setCacheStorage( Factory::createStorage() ) # or a method of other service: - setCacheStorage( @factory::createStorage() ) ~~~ 或者,新创建的类实例: ~~~ setup: - setCacheStorage( Nette\Caching\Storages\FileStorage(%tempDir%) ) # generates: $service->setCacheStorage(new Nette\Caching\Storages\FileStorage(...)); ~~~ 您还可以设置属性的值: 替换 ~~~ setup: - $substitutions( [db: test] ) # generates: $service->substitutions = ['db' => 'test']; ~~~ 完整示例: ~~~ parameters: database: driver: mysql host: localhost dbname: test user: jim password: beam substitutions: db: test services: database: class: Nette\Database\Connection( '%database.driver%:host=%database.host%;dbname=%database.dbname%', %database.user%, %database.password%, null, Nette\Database\Reflection\DiscoveredReflection() ) setup: - setCacheStorage - $substitutions( %database.substitutions% ) ~~~ # 匿名服务 之后的时间有一些服务,实际上没有在配置文件中的任何其他地方引用。 在这种情况下命名这些服务不是必需的。 要定义匿名服务,请使用以下语法: ~~~ services: - Simple\Service - class: Complex\Service setup: - setLang(%lang%) ~~~ 要引用这样的匿名服务,您将需要使用完全限定类名称。 ~~~ services: router: @App\RouterFactory::createRouter ~~~ 请记住,从匿名服务的性质,不可能注册多个相同类型,因为它会导致歧义。 # 服务定义继承 ~~~ services: dev_database < database setup: - Diagnostics\ConnectionPanel::initialize ~~~ # Auto-wiring 自动布线功能可以自动将依赖传递到服务的构造函数和方法。 它使用typehinting和@return注释。 只有一个服务匹配容器中的类型,否则抛出异常。 要定义多个相同类型的服务,我们需要将它们从自动布线中排除: ~~~ services: cacheStorage: class: Nette\Caching\Storages\FileStorage(%tempDir%) tempCacheStorage: class: Nette\Caching\Storages\DevNullStorage autowired: no ~~~ 当修改Nette Framework的核心服务时,我们需要确保容器知道我们想要使用的类。 这意味着在@return注释中使用完全限定类名或者用类条目设置FQ类名。 # 多个配置文件 使用includes部分添加更多配置文件。 ~~~ includes: - parameters.php - services.neon - presenters.neon ~~~ 配置合并过程将包含包含部分和最低优先级的文件的最高优先级分配给第一个包含的文件。 要防止合并某个数组,请在数组名称后面使用感叹号: ~~~ argument!: [1, 2, 3] ~~~