gpt4 book ai didi

performance - 与选民的 symfony 表演

转载 作者:行者123 更新时间:2023-12-02 03:20:07 25 4
gpt4 key购买 nike

在我的 symfony 应用程序中,我使用选民来检查用户是否可以访问某些功能。

现在,我有一个导航栏,其中的菜单根据这些权限显示或隐藏。

这个导航栏单独渲染大约需要 2 秒。每个页面都添加了很多内容。如果我注释掉导航栏的 render_controller,我将获得 2 秒。如果我在每个选民 is_granted 方法的顶部返回 true,我将获得 1.5 秒。

我该如何解决这个问题?使用缓存?不使用选民?简化我的选民?使用选民不是最佳做法吗?即使 symfony 必须根据所有属性列表检查属性?

我的导航栏生成器:

<?php

namespace AppBundle\Menu;

use AppBundle\Application\Core\ExplorerManager;
use AppBundle\Entity\User\Associate;
use AppBundle\Entity\User\Role;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Translation\Translator;

class MenuBuilder
{
/**
* @var Router
*/
private $router;
/**
* @var Translator
*/
private $translator;
/**
* @var AuthorizationChecker
*/
private $authorizationChecker;

/**
* @param Router $router
* @param Translator $translator
* @param AuthorizationChecker $authorizationChecker
*/
public function __construct(Router $router, Translator $translator, AuthorizationChecker $authorizationChecker)
{
$this->router = $router;
$this->translator = $translator;
$this->authorizationChecker = $authorizationChecker;
}

public function getFrontendHeaderMenuItems($isAuthenticated)
{
$menuItems = array(
array(
'title' => 'pricing',
'route' => 'cms',
'route_parameters' => array('dir' => 'general', 'page' => 'foodmeup_premium')
),
// array(
// 'title' => 'recipes',
// 'route' => 'explore',
// 'route_parameters' => array('object' => ExplorerManager::RECETTE)
// ),
array(
'title' => 'blog',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::BLOG)
),
array(
'title' => 'contact',
'route' => 'message_foodmeup'
)
);

if (false == $isAuthenticated) {
$menuItems[] = array(
'title' => 'login',
'route' => 'login'
);
}

$menuItems = $this->generateMenuRoutes(
$menuItems,
'frontend_bars',
array()
);

return $menuItems;
}

public function getBackendLeftSidebarMenuItems()
{
$menuItems = array(
array(
'title' => 'dashboard',
'icon' => 'th-large',
'route' => 'dashboard'
),
array(
'title' => 'administration',
'icon' => 'star',
'is_granted' => Role::ROLE_ADMIN,
'children' => array(
array(
'title' => 'dashboard',
'route' => 'admin_dashboard',
),
array(
'title' => 'moderation',
'route' => 'moderate_posts',
),
array(
'title' => 'users',
'route' => 'switch_user',
'is_granted' => Role::ROLE_SUPERADMIN,
),
array(
'title' => 'subscriptions',
'route' => 'grant_partner_subscription',
'is_granted' => Role::ROLE_SUPERADMIN,
)
)
), array(
'title' => 'ingredients',
'icon' => 'flask',
'children' => array(
array(
'title' => 'explore_ingredients',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::CONSOMMABLE)
),
array(
'title' => 'my_ingredients',
'route' => 'user_ingredients_display',
'is_granted' => Associate::READ_INGREDIENT
), array(
'title' => 'create_import',
'route' => 'edit_ingredient',
'is_granted' => Associate::EDIT_INGREDIENT
), array(
'title' => 'stock',
'route' => 'set_ingredient_stock',
'is_granted' => Associate::READ_STOCK,
), array(
'title' => "buying_cost",
'route' => 'parameter_cost',
'is_granted' => Associate::READ_COST,
)
)
), array(
'title' => 'recipes',
'icon' => 'birthday-cake',
'children' => array(
array(
'title' => 'explore_recipes',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::RECETTE)
),
array(
'title' => 'my_recipes',
'route' => 'user_recipes_display',
'is_granted' => Associate::READ_RECIPE
), array(
'title' => 'create',
'route' => 'edit_recipe',
'is_granted' => Associate::EDIT_RECIPE
), array(
'title' => 'print',
'route' => 'print_recipes',
'is_granted' => Associate::READ_RECIPE
)
)
), array(
'title' => 'plannings',
'icon' => 'tasks',
'is_granted' => array(Associate::READ_PLANNING, Associate::EDIT_PLANNING, Associate::DELETE_PLANNING),
'children' => array(
array(
'title' => 'my_plannings',
'route' => 'display_plannings',
'is_granted' => Associate::READ_PLANNING
), array(
'title' => 'my_models',
'route' => 'display_plannings',
'route_parameters' => array('isModel' => true),
'is_granted' => Associate::READ_PLANNING
), array(
'title' => 'create_planning',
'route' => 'edit_planning',
'is_granted' => array(Associate::EDIT_PLANNING, Associate::CREATE_MODEL)
)
)
), array(
'title' => 'orders',
'icon' => 'phone',
'is_granted' => array(Associate::READ_ORDER, Associate::EDIT_ORDER, Associate::EDIT_ORDER, Associate::DELETE_ORDER),
'children' => array(
array(
'title' => 'my_orders',
'route' => 'display_planning_orders',
'is_granted' => Associate::READ_ORDER
), array(
'title' => 'automatic_order',
'route' => 'automatic_order',
'is_granted' => Associate::EDIT_ORDER
), array(
'title' => 'edit_order',
'route' => 'edit_order',
'is_granted' => Associate::EDIT_ORDER
)
)
), array(
'title' => 'suppliers',
'icon' => 'truck',
'is_granted' => array(Associate::EDIT_SUPPLIER, Associate::READ_SUPPLIER, Associate::DELETE_SUPPLIER),
'children' => array(
array(
'title' => 'my_suppliers',
'route' => 'display_suppliers',
'is_granted' => Associate::READ_SUPPLIER
), array(
'title' => 'select',
'route' => 'user_supplier_select',
'is_granted' => Associate::EDIT_SUPPLIER
), array(
'title' => 'create',
'route' => 'edit_organization',
'route_parameters' => array('category_slug' => 'fournisseur-de-consommables'),
'is_granted' => Associate::EDIT_SUPPLIER
)
)
), array(
'title' => 'teams',
'icon' => 'users',
'is_granted' => array(Associate::EDIT_TEAM, Associate::READ_TEAM, Associate::DELETE_TEAM, Associate::MANAGE_RIGHTS),
'children' => array(
array(
'title' => 'my_teams',
'route' => 'teams_display',
), array(
'title' => 'worker_parameter',
'route' => 'worker_parameter',
'is_granted' => Associate::EDIT_TEAM,
)
)
)
);

$menuItems = $this->generateMenuRoutes($menuItems, 'backend_bars', array());

return $menuItems;
}

private function generateMenuRoutes(Array $menuItems, $domain, $isGranted)
{
foreach ($menuItems as $key => $menuItem) {
if (array_key_exists('is_granted', $menuItems[$key])) {
$rights = is_array($menuItems[$key]['is_granted']) ? $menuItems[$key]['is_granted'] : array($menuItems[$key]['is_granted']);

$rights = array_map(function ($right) {
return $this->authorizationChecker->isGranted($right);
}, $rights);

if (in_array(true, $rights) == false) {
unset($menuItems[$key]);
continue;
}
}

if (array_key_exists('route', $menuItems[$key])) {
$menuItems[$key]['uri'] = $this->router->generate($menuItems[$key]['route'], array_key_exists('route_parameters', $menuItems[$key]) ? $menuItems[$key]['route_parameters'] : array());
} else {
$menuItems[$key]['uri'] = '#/';
}

$menuItems[$key]['title'] = $this->translator->trans($menuItems[$key]['title'], array(), $domain);
if (array_key_exists('children', $menuItems[$key])) {
$menuItems[$key]['children'] = $this->generateMenuRoutes($menuItems[$key]['children'], $domain, $isGranted);
}
}

return $menuItems;
}

public function extractTitles(Array $menuItems)
{
$titles = array();

foreach ($menuItems as $key => $menuItem) {
$titles[] = $menuItems[$key]['title'];
if (array_key_exists('children', $menuItems[$key])) {
$titles = array_merge($titles, $this->extractTitles($menuItems[$key]['children']));
}
}

return $titles;
}
}

最佳答案

选民有表现上的缺点。因此,如果您需要更高的性能,那么最好使用 ACL 或优化选民加载,因为在执行每次安全检查时,symfony 会遍历所有选民。

假设您的菜单中有 30 个链接,并且有 20 个投票者。当您在 1 个循环中检查对所有链接的访问时,symfony 将调用投票者 600 次(他们中的大多数人将立即返回 Voter::ACCESS_ABSTAIN,但这仍然需要时间,在您的情况下需要太多时间)。

关于performance - 与选民的 symfony 表演,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34120083/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com