亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Symfony 5 從控制臺命令生成 URL

Symfony 5 從控制臺命令生成 URL

PHP
江戶川亂折騰 2023-05-12 16:06:53
我是 Symfony 的新手,正在使用 5.x。我已經使用 Symfony\Component\Console\Command\Command 創建了一個控制臺命令,并且正在嘗試使用 Symfony\Component\HttpClient\HttpClient 來 POST 到一個 URL。我需要生成在同一臺機器上運行的路由的 URL(但將來這可能會更改為不同的機器),因此主機可能類似于 localhost 或 example.com,并且 API 的端口是自定義的。我在網上搜索過,但我得到的唯一可能的解決方案是使用 Symfony\Component\Routing\Generator\UrlGeneratorInterface,并且網上充斥著舊版本 Symfony 的代碼示例,我還沒有設法得到這個工作。我最近的嘗試是:public function __construct(UrlGeneratorInterface $router){    parent::__construct();    $this->router = $router;}但我真的不明白如何將參數 UrlGeneratorInterface $router 注入構造函數。我收到未提供參數的錯誤。我是否必須在其他地方創建 UrlGenerator 的實例并將其注入此處,或者是否有更簡單的方法從命令中生成 Symfony 中的絕對 URL?我還不太了解容器。$url = $context->generate('view', ['Param' => $message['Param']], UrlGeneratorInterface::ABSOLUTE_URL);服務.yaml:App\Command\MyCommand:    arguments: ['@router.default']是否有更簡單的方法通過顯式指定主機、協議、端口、路由、參數等從控制臺命令生成 URL?為什么 UrlGeneratorInterface 或 RouterInterface 不自動裝配?如果我還啟用了自動裝配,是否需要在 services.yaml 中手動指定接線為 $router.default ?我知道執行函數的實現可能不正確,但如果不先讓構造函數工作,我就無法修復它。這仍在進行中。
查看完整描述

3 回答

?
慕田峪4524236

TA貢獻1875條經驗 獲得超5個贊

private $router您似乎遇到的問題不是由于您的服務聲明,而是您缺少中變量的聲明MyCommand。

因此,您可以保留services.yaml要點中顯示的內容,無需更改自動裝配變量,也不必手動聲明命令

此外,您不需要$context從路由器中獲取,您也可以在您的 中設置基本 URLframework.yaml,在這里您可以找到我找到它的位置。

請注意,我從執行中刪除了一些代碼,這是因為我無法訪問您的其他文件。你可以重新添加這個。


查看完整回答
反對 回復 2023-05-12
?
慕斯709654

TA貢獻1840條經驗 獲得超5個贊

好吧,解決這個問題并不是那么簡單。許多文檔已過時或未完全解決此問題。這是我到目前為止得到的:


服務.yaml:


Symfony\Component\Routing\RouterInterface:

? ? arguments: ['@router']

應用程序.php:


#!/usr/bin/env php

<?php

// application.php


require __DIR__.'/vendor/autoload.php';

require __DIR__.'/src/Kernel.php';


use Symfony\Bundle\FrameworkBundle\Console\Application;

use Symfony\Component\Routing\RouterInterface;

use Symfony\Component\Dotenv\Dotenv;


$dotenv = new Dotenv();

$dotenv->load(__DIR__.'/.env', __DIR__.'/.env.local');


$kernel = new App\Kernel(getenv('APP_ENV'), getenv('APP_DEBUG'));

$kernel->boot();


$container = $kernel->getContainer();


$application = new Application($kernel);


$application->add(new App\Command\MyCommand($container->get('router')));


$application->run();

注意:我將應用程序導入更改為 Symfony\Bundle\FrameworkBundle\Console\Application


我的命令.php:


<?php

// src/Command/MyCommand.php

namespace App\Command;


use Symfony\Component\Console\Command\Command;

use Symfony\Component\Console\Command\LockableTrait;

use Symfony\Component\Console\Input\InputInterface;

use Symfony\Component\Console\Output\OutputInterface;

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

use Symfony\Component\Routing\RouterInterface;

use Symfony\Component\HttpClient\HttpClient;

use App\SQSHelper;


class MyCommand extends Command

{

? ? use LockableTrait;


? ? // the name of the command (the part after "bin/console")

? ? protected static $defaultName = 'app:my-command';


? ? protected $router;


? ? public function __construct(RouterInterface $router)

? ? {

? ? ? ? parent::__construct();

? ? ? ? $this->router = $router;

? ? }


? ? protected function configure()

? ? {

? ? }


? ? protected function execute(InputInterface $input, OutputInterface $output)

? ? {

? ? ? ? if($this->lock()) { // Prevent running more than one instance

? ? ? ? ? ? $endpoint =?

? ? ? ? ? ? $queueName = 'Queue';

? ? ? ? ? ? $queue = new SQSHelper();


? ? ? ? ? ? while($queue->getApproxNumberOfMessages($queueName)) {

? ? ? ? ? ? ? ? $message = $queue->receiveMessage($queueName);

? ? ? ? ? ? ? ? if($message) {

? ? ? ? ? ? ? ? ? ? if($message['__EOQ__'] ?? FALSE) // End-of-Queue marker received

? ? ? ? ? ? ? ? ? ? ? ? break;


? ? ? ? ? ? ? ? ? ? $context = $this->router->getContext();

? ? ? ? ? ? ? ? ? ? $context->setHost('localhost');

? ? ? ? ? ? ? ? ? ? $context->setHttpPort('49100');

? ? ? ? ? ? ? ? ? ? $context->setHttpsPort('49100');

? ? ? ? ? ? ? ? ? ? $context->setScheme('https');

? ? ? ? ? ? ? ? ? ? $context->setBaseUrl('');


? ? ? ? ? ? ? ? ? ? $url = $this->router->generate('ep', ['MessageId' => $message['MessageId']], UrlGeneratorInterface::ABSOLUTE_URL);


? ? ? ? ? ? ? ? ? ? $client = HttpClient::create();

? ? ? ? ? ? ? ? ? ? $response = $client->request('POST', $url, [

? ? ? ? ? ? ? ? ? ? ? ? 'headers' => ['Content-Type' => 'application/json'],

? ? ? ? ? ? ? ? ? ? ? ? 'body' => $message['Body'] // Already JSON encoded

? ? ? ? ? ? ? ? ? ? ]);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }


? ? ? ? ? ? $this->release(); // Release lock


? ? ? ? ? ? // this method must return an integer number with the "exit status code"

? ? ? ? ? ? // of the command. You can also use these constants to make code more readable


? ? ? ? ? ? // return this if there was no problem running the command

? ? ? ? ? ? // (it's equivalent to returning int(0))

? ? ? ? ? ? return Command::SUCCESS;


? ? ? ? ? ? // or return this if some error happened during the execution

? ? ? ? ? ? // (it's equivalent to returning int(1))

? ? ? ? ? ? // return Command::FAILURE;

? ? ? ? }

? ? }

}

如果有什么感覺不對,或者如果您可以提供更好的解決方案或改進,請貢獻...


查看完整回答
反對 回復 2023-05-12
?
忽然笑

TA貢獻1806條經驗 獲得超5個贊

Symfony 5.1 引入的解決方案:


https://symfony.com/doc/current/routing.html#generating-urls-in-commands


在命令中生成 URL 與在服務中生成 URL 的工作方式相同。唯一的區別是命令不在 HTTP 上下文中執行。因此,如果您生成絕對 URL,您將獲得 http://localhost/ 作為主機名,而不是您的真實主機名。


解決方案是配置 default_uri 選項來定義命令在生成 URL 時使用的“請求上下文”:


# config/packages/routing.yaml

framework:

    router:

        # ...

        default_uri: 'https://example.org/my/path/'


查看完整回答
反對 回復 2023-05-12
  • 3 回答
  • 0 關注
  • 195 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號