小编yiv*_*ivi的帖子

即使对于用户www-data可写,is_writable对于NFS共享也返回false

我有一个相对的文件夹'files / crm-upload',我想在其中上传文件。我的代码检查is_writable()是否为true,只有在这种情况下才继续进行。

该文件夹作为带有rw和sec = sys的NFS共享挂载。

我已经编写了一个测试脚本,我也在apache上执行了该脚本以查看访问权限,结果是:

files/crm-upload/php_touch modification time has been changed to present time 
My effective UID is 33 but my UID is really 33
files/crm-upload/ is owned by 33 and has permissions 40777
is_readable('files/crm-upload/') gives true
is_readable('files/crm-upload/php_touch') gives true
is_writable('files/crm-upload/') gives false
is_writable('files/crm-upload/php_touch') gives true
is_writable('files/crm-upload/25/') gives true
is_writable('files/images/') gives true
file_exists('files/crm-upload/') gives true
file_exists('files/crm-upload/php_touch') gives true
Some stat uids: 

files/crm-upload/: 33
files/crm-upload/php_touch: 33
files/images/: 33
Run Code Online (Sandbox Code Playgroud)

所以:

  • 触摸共享上的文件有效
  • uid是正确的
  • 目录具有正确的权限
  • 共享中的子文件夹和文件的is_writable返回true

怎么可能只有已挂载共享的根文件夹不可写,而其他所有东西都不能写?

这是Ubuntu 18.04。客户端,没有运行SELinux ...

php linux apache ubuntu nfs

5
推荐指数
1
解决办法
168
查看次数

通过可迭代的类名获取服务-注入标记的服务

我正在努力通过类别名称从注入的已标记服务组中获取特定服务。

这是一个示例:我标记实现DriverInterface为的所有服务app.driver并将其绑定到$drivers变量。

在其他一些服务中,我需要获取所有已标记app.driver并实例化的驱动程序,并且仅使用其中一些驱动程序。但是需要的驱动程序是动态的。

services.yml

_defaults:
        autowire: true
        autoconfigure: true
        public: false
        bind:
            $drivers: [!tagged app.driver]

_instanceof:
        DriverInterface:
            tags: ['app.driver']
Run Code Online (Sandbox Code Playgroud)

其他一些服务:

/**
 * @var iterable
 */
private $drivers;

/**
 * @param iterable $drivers
 */
public function __construct(iterable $drivers) 
{
    $this->drivers = $drivers;
}

public function getDriverByClassName(string $className): DriverInterface
{
    ????????
}
Run Code Online (Sandbox Code Playgroud)

因此,将实现的服务DriverInterface注入到$this->driversparam中作为可迭代的结果。我只能foreach通过它们,但是所有服务都将被实例化。

是否有其他方法可以将这些服务注入,以通过类名从它们获得特定服务而无需实例化其他服务?

我知道有可能将那些驱动程序公开并改为使用容器,但是我想避免以其他方式将容器注入服务中。

php autowired symfony symfony-dependency-injection

5
推荐指数
2
解决办法
285
查看次数

Git 从composer.json 保存部署令牌url,防止推送到存储库

我正在开发一个基于模块的 Laravel CMS。

这是私有的,这意味着我需要使用 git 部署令牌,因此我可以使用 Composer 来安装/管理这些模块。

例子:

"repositories"      : {
"repo-name": {
  "type": "vcs",
  "url": "https://gitlab+deploy-token-xxxxx:password@gitlab.com/url-to-repo.git"
},
Run Code Online (Sandbox Code Playgroud)

这通常工作得很好,这意味着当我创建一个新项目时,我可以安装我的模块。

但是 Windows / Git 将部署令牌保存为 Windows 中的 Git 凭据,覆盖了我的正常登录。

这意味着,当我开发模块并想要推送更改时,Gitlab 会拒绝它,因为 Git 尝试使用部署密钥而不是我的正常 Git 凭据来上传我的更改。

我的问题:是否有可能以某种方式阻止 Git 将此部署令牌保存为全局 Git 凭证,这样它就不会覆盖我常用的 Git 凭证?

git composer-php

5
推荐指数
1
解决办法
1425
查看次数

Symfony 使用 Redis 作为默认缓存编译容器

我有一个 Symfony 应用程序,我想使用 Redis 作为缓存系统。Symfony 开箱即用的默认缓存系统是文件系统缓存。

从文档中我了解到 Symfony 中有两个命名缓存;cache.app因此cache.system我使用以下 cache.yaml 将两者设置为 Redis:

framework:
    cache:
    # Put the unique name of your app here: the prefix seed
    # is used to compute stable namespaces for cache keys.
    prefix_seed: myteam/myapp

    default_redis_provider: "redis://redis:6379"

    # The app cache caches to the filesystem by default.
    # Other options include:

    # cache.app via Redis
    app: cache.adapter.redis

    # cache.system also
    system: cache.adapter.redis
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我加载了一个示例页面并监视了缓存文件夹。我发现尽管在 Redis 中创建了密钥,但仍在缓存文件夹中创建文件。

我知道 Symfony 不建议弄乱内核在文件缓存中创建的文件,但即使是 cache/prod/Containerxxxxx 文件夹也会被写入。

不属于应用程序或系统的文件夹中可能会缓存什么?是否有另一个我错过的命名缓存?

php caching redis symfony

5
推荐指数
1
解决办法
3230
查看次数

如果我没有/无法使用 DI 注入服务,如何直接从容器获取服务?

我有一部分代码,通过依赖注入注入两个$checker服务$paginator。它工作完美:

public function index(Request $request, Paginator $paginator, Checker $checker)
    {
        $result = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
        $partialResult = $paginator->getPartial($result, 0, 3);
        $checker->isValid('A');
        var_dump("test");
        die;
    }
Run Code Online (Sandbox Code Playgroud)

文件配置如下services.yaml

   paginator:
        public: true
        class: 'App\Helper\Paginator'

    checker:
        public: true
        class: 'App\Helper\Checker'
        arguments:
         $paginator: '@paginator'
Run Code Online (Sandbox Code Playgroud)

但由于某些原因我想通过方法注入服务:

$checker = $this->container->get('checker');
Run Code Online (Sandbox Code Playgroud)

但这不起作用。在以前的版本中,Symfony 就像 3.4 一样。

我收到错误:

找不到服务“检查器”:事件虽然存在于应用程序的容器中,但“App\Controller\DefaultController”内的容器是一个较小的服务定位器,只知道“http_kernel”、“parameter_bag”、“request_stack”、“router” ”、“会话”和“树枝”服务。尝试使用依赖注入来代替。

我应该如何解决这个问题?

php dependency-injection service-locator symfony symfony4

5
推荐指数
1
解决办法
4468
查看次数

如何注入一组实现相同接口的服务,而不声明每个服务的连接?

我正在开发一个应用程序,其中有一些处理程序作为我希望能够调用的服务。他们都实现了一个ItemHandlerInterface.

我希望能够在控制器中检索所有ItemHandlerInterface服务集合,而无需手动连接它们。

到目前为止,我具体标记了它们:

服务.yaml

_instanceof:
    App\Model\ItemHandlerInterface:
        tags: [!php/const App\DependencyInjection\ItemHandlersCompilerPass::ITEM_HANDLER_TAG]
        lazy: true
Run Code Online (Sandbox Code Playgroud)

并尝试在控制器中检索我的服务集合。如果只有一个服务实现,它就可以工作ItemHandlerInterface,但是一旦我创建了多个服务(如下面的TestHandler和 )Test2Handler,我最终会得到一个The service "service_locator.03wqafw.App\Controller\ItemUpdateController" has a dependency on a non-existent service "App\Model\ItemHandlerInterface".

如何动态检索实现我的接口的所有服务?

一种肮脏的解决方案是强制所有ItemHandlerInterface内容public: true并传递Container给我的控制器构造函数。但这很丑陋,我想找到一种更优雅的方式。

项目更新控制器

namespace App\Controller;

use App\Model\ItemHandlerInterface;
use App\Service\ItemFinder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Debug\Exception\ClassNotFoundException;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use App\Model\Item;
use Psr\Container\ContainerInterface;

/**
 * Class ItemUpdateController
 *
 * @package App\Controller
 */
class ItemUpdateController extends AbstractController
{
    /**
     * …
Run Code Online (Sandbox Code Playgroud)

php dependency-injection symfony

5
推荐指数
1
解决办法
5826
查看次数

如何避免记录由 Api-Platform 正确转换为状态代码的预期异常?

在我们的 Api-Platform 项目的一些路线中,throw对于一些常见的错误情况,例外是n。

例如,在调用 时POST /ordersNewOrderHandler如果合适,可以抛出这两个中的任何一个:

  • NotEnoughStock
  • NotEnoughCredit

所有这些异常都属于一个DomainException层次结构。

这些异常通过使用配置正确转换400响应上的状态代码exception_to_status,并且响应包括适当的错误消息。到现在为止还挺好。

exception_to_status:
    App\Order\NotEnoughStock: !php/const Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST
    App\Order\NotEnoughCredit: !php/const Symfony\Component\HttpFoundation\Response::HTTP_BAD_REQUEST
Run Code Online (Sandbox Code Playgroud)

唯一的问题是异常仍被记录为CRITICAL错误,被视为“未捕获的异常”。即使在生产中,这也会被记录下来。

我原以为通过转换为正确的状态代码(例如!== 500),这些异常将被视为“已处理”,因此不会污染日志。

从处理程序抛出异常很方便,因为它有助于处理事务并自动生成适当的错误响应消息。它适用于网络和控制台。

这些交易不应该被视为已处理吗?是否有必要创建另一个异常侦听器来处理这个问题?如果创建异常侦听器,如何做才能不干扰 Api-Platform 错误规范化?

php error-handling symfony api-platform.com

5
推荐指数
1
解决办法
834
查看次数

无法安装 symfony/maker-bundle

我是 Symfony 的新手,我尝试安装symfony/maker-bundle,但它给了我以下错误:

Using version ^1.22 for symfony/maker-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.4.*"
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - ocramius/proxy-manager 2.9.0 requires composer-runtime-api ^2.0.0 -> no matching package found.
    - ocramius/proxy-manager 2.9.0 requires composer-runtime-api ^2.0.0 -> no matching package found.
    - ocramius/proxy-manager 2.9.0 requires composer-runtime-api ^2.0.0 -> no matching package found.
    - Installation …
Run Code Online (Sandbox Code Playgroud)

php symfony composer-php

5
推荐指数
1
解决办法
2051
查看次数

如何在发送前获取模板电子邮件的渲染正文?

我想在发送之前获得电子邮件的渲染。

我创建了一个TemplatedEmailwithhtmlTemplatecontext,它可以很好地发送,但是如何使用上下文获取生成的模板以将其保存在数据库中?(客户的需求)

我尝试过,getBody()但似乎只适用于文本模板,因为我得到A message must have a text or an HTML part or attachments.

$email = new TemplatedEmail();
$email->htmlTemplate($htmlTemplate);
$email->from($from)->to(...$to)->subject($subject);
$email->context($context);

dd($email->getBody());
Run Code Online (Sandbox Code Playgroud)

我想使用渲染方法,但我在服务中,不确定这是否是存储在数据库中的好方法。

php symfony symfony-mailer

5
推荐指数
1
解决办法
3139
查看次数

在 PHP 中通过 PhpStan 使用 Enum 作为字符串

我正在 Symfony 6 应用程序中试验 PHP 枚举,我认为我找到了一个非常好的用例。一切正常,但 phpstan 一直抱怨我返回的类型。

 ------ -----------------------------------------------------------------------------------------------------------------------------------------------
  Line   src/Entity/User.php
 ------ -----------------------------------------------------------------------------------------------------------------------------------------------
  93     Return type (array<App\Security\Roles>) of method App\Entity\User::getRoles() should be compatible with return type (array<string>) of method
         Symfony\Component\Security\Core\User\UserInterface::getRoles()
 ------ -----------------------------------------------------------------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

我的枚举看起来像这样:

namespace App\Security;

enum Roles: string
{
    case Admin = 'ROLE_ADMIN';
    case User = 'ROLE_USER';
}
Run Code Online (Sandbox Code Playgroud)

在我User实现的实体中Symfony\Component\Security\Core\User\UserInterface,我有这个:

/**
 * @see UserInterface
 * @return array<Roles>
 */
public function getRoles(): array
{
    $roles = $this->roles;
    // guarantee every user at least has ROLE_USER
    $roles[] = …
Run Code Online (Sandbox Code Playgroud)

php enums static-analysis symfony phpstan

5
推荐指数
1
解决办法
2840
查看次数