идёт обращение сразу напрямую к глобальным переменным и во мне всё протестует.
class FirstException extend ModuleException {}
class SecondException extend ModuleException {}
class ModuleFirst
{
public function work()
{
throw new FirstException('first);
}
}
class ModuleSecond
{
public function work()
{
throw new SecondException('second);
}
}
try {
$module->work();
} catch(ModuleException $e) {
// обработка
}
class FirstException {}
class SecondException {}
class ModuleFirst
{
public function work()
{
try {
$module2->work();
} catch(SecondException $e) {
throw new FirstException($e->getMessage, 0, $e);
}
}
}
class ModuleSecond
{
public function work()
{
throw new SecondException('second);
}
}
try {
$module1->work();
} catch(FirstException $e) {
// обработка
}
twig.extension
By default, the form will redirect to the URL the user requested (i.e. the URL which triggered the login form being shown). For example, if the user requestedhttp://www.example.com/admin/post/18/edit
, then after they have successfully logged in, they will be sent back tohttp://www.example.com/admin/post/18/edit.
Redirecting after Success¶
always_use_default_target_path
: при анализе код увидел, что постоянно лазию в бд за одной записью (за одной и той же), чего, конечно же хотелось бы избежать. посоветуйте пожалуйста, как передавать данные между объектами?Есть такой подход как UnitOfWork, в котором складываются объекта из персистенс слоя (слоя хранения), соответственно когда идет повторное обращение — запрос в БД не идет...
использую АR.А вот тут проблема, тк AR модуль — кусок работы БД, а не отделенная от нее штука. То есть она (модель) ходит в хранилище, а не за ней куда-то и кто-то ходите... Ярчайший пример, когда нарушение SRP очень больно сказывается.
ON CONFLICT (expression) DO NOTHING
и похожие решения в других СУБД могут быть иногда довольно подходящими в виду простоты реализации...$sql = <<<SQL
INSERT INTO table (id, value)
VALUES (555, \'uniqValue\')
ON CONFLICT (value) DO NOTHING
SQL;
$this->em->getConnection()->executeQuery($sql);
<?php
$values = [
['value' => 'One', 'weight' => 20],
['value' => 'Two', 'weight' => 30],
['value' => 'Three', 'weight' => 50]
];
function randByWeight(array $arr) {
$max = 0;
$result = [];
foreach($arr as $value) {
$rand = pow((mt_rand() / (mt_getrandmax() + 1)), 1/$value['weight']);
if ($rand > $max) {
$max = $rand;
$result = $value;
}
}
return $result;
}
// Например: 'Three' выпадет в 50% случаев, тк его вес -- половина от суммы всех весов
// Например: 'Two' выпадет в 30% случаев, тк его вес -- 30% от суммы всех весов
var_dump(randByWeight($values));
SELECT * FROM table ORDER BY POWER(random(), 1/weight) DESC LIMIT 1
<?php
$values = [
['value' => 'One', 'weight' => 20],
['value' => 'Two', 'weight' => 30],
['value' => 'Three', 'weight' => 50]
];
function randByWeight(array $items) {
$sum = array_reduce($items, function(int $acc, array $item): int {
return $acc += $item['weight'];
}, 0);
$rand = (mt_rand() / (mt_getrandmax() + 1)) * $sum;
foreach($items as $item) {
if($rand < $item['weight']) {
return $item;
}
$rand -= $item['weight'];
}
}
// Например: 'Three' выпадет в 50% случаев, тк его вес -- половина от суммы всех весов
// Например: 'Two' выпадет в 30% случаев, тк его вес -- 30% от суммы всех весов
var_dump(randByWeight($values));
<?php
class Any
{
private $a;
public function __construct(string $a)
{
$this->a = $a;
}
// Простое клонирование 1 в 1
public function copy1(): self
{
return clone $this;
}
// Для примера, как сделать похожий объект на основе состояния текущего объекта
public function copy2(): self
{
$new = new self($this->a);
// тут делаем еще что-либо
// $new->a тут доступна напрямую
return $new;
}
// Меняем состояние и возвращаем новый объект, иммутабельное поведение
// хорошая практика
public function withNewA(string $a): self
{
$new = clone $this;
$new->a = $a;
return $new;
}
}
$any = new Any("A");
var_dump($any === $any->copy1()); // false
var_dump($any === $any->copy2()); // false
var_dump($any === $any->withNewA('B')); // false, изменили объект, но получили новый, а не измененный старый
<?php
$input = '{"success":true,"data":[{"sport_key":"soccer_korea_kleague1","sport_nice":"K League 1","teams":["Jeonbuk Hyundai Motors","Suwon Samsung Bluewings"],"commence_time":1588932000,"home_team":"Jeonbuk Hyundai Motors","sites":[{"site_key":"unibet","site_nice":"Unibet","last_update":1588281960,"odds":{"h2h":[1.75,3.85,3.7]}},{"site_key":"sport888","site_nice":"888sport","last_update":1588282210,"odds":{"h2h":[1.74,3.8,3.65]}},{"site_key":"onexbet","site_nice":"1xBet","last_update":1588282134,"odds":{"h2h":[1.87,3.96,3.5]}},{"site_key":"betfair","site_nice":"Betfair","last_update":1588281947,"odds":{"h2h":[1.68,1.28,1.25],"h2h_lay":[85.0,85.0,85.0]}},{"site_key":"paddypower","site_nice":"Paddy Power","last_update":1588281989,"odds":{"h2h":[1.67,4.2,3.6]}}],"sites_count":5},{"sport_key":"soccer_korea_kleague1","sport_nice":"K League 1","teams":["Sangju Sangmu FC","Ulsan Hyundai FC"],"commence_time":1589000400,"home_team":"Ulsan Hyundai FC","sites":[{"site_key":"unibet","site_nice":"Unibet","last_update":1588281960,"odds":{"h2h":[3.85,1.88,3.3]}},{"site_key":"sport888","site_nice":"888sport","last_update":1588282210,"odds":{"h2h":[3.8,1.85,3.25]}},{"site_key":"onexbet","site_nice":"1xBet","last_update":1588282134,"odds":{"h2h":[3.76,1.92,3.5]}}],"sites_count":3},{"sport_key":"soccer_korea_kleague1","sport_nice":"K League 1","teams":["Daegu FC","Incheon United"],"commence_time":1589009400,"home_team":"Incheon United","sites":[{"site_key":"unibet","site_nice":"Unibet","last_update":1588281960,"odds":{"h2h":[2.23,2.95,3.2]}},{"site_key":"sport888","site_nice":"888sport","last_update":1588282210,"odds":{"h2h":[2.2,2.9,3.2]}},{"site_key":"onexbet","site_nice":"1xBet","last_update":1588282134,"odds":{"h2h":[2.28,2.98,3.3]}}],"sites_count":3},{"sport_key":"soccer_korea_kleague1","sport_nice":"K League 1","teams":["Sangju Sangmu FC","Seongnam FC"],"commence_time":1589018400,"home_team":"Sangju Sangmu FC","sites":[{"site_key":"unibet","site_nice":"Unibet","last_update":1588281960,"odds":{"h2h":[2.38,2.75,3.2]}},{"site_key":"sport888","site_nice":"888sport","last_update":1588282210,"odds":{"h2h":[2.35,2.7,3.15]}}],"sites_count":2},{"sport_key":"soccer_korea_kleague1","sport_nice":"K League 1","teams":["FC Seoul","Gangwon FC"],"commence_time":1589095800,"home_team":"Gangwon FC","sites":[{"site_key":"unibet","site_nice":"Unibet","last_update":1588281960,"odds":{"h2h":[2.38,2.75,3.2]}},{"site_key":"sport888","site_nice":"888sport","last_update":1588282210,"odds":{"h2h":[2.35,2.7,3.15]}},{"site_key":"onexbet","site_nice":"1xBet","last_update":1588282134,"odds":{"h2h":[2.42,2.84,3.2]}}],"sites_count":3}]}';
$data = json_decode($input, true);
function grabBookerData(array $data, string $bookerName): array {
return array_map(function(array $item) use ($bookerName) {
// Собираем результирующий объект события
$event = new \stdClass();
$event->sport_nice = $item['sport_nice'] ?? null;
$event->teams = $item['teams'] ?? [];
// Из данных по разным букмекерам оставляем h2h, который нам нужен
$bookersData = array_column($item['sites'], null, 'site_key');
$event->h2h = $bookersData[$bookerName]['odds']['h2h'] ?? [];
return $event;
}, $data['data'] ?? []);
}
var_dump(grabBookerData($data, 'unibet')); // итоговый набор данных
$this->anyMock
->expects($this->exactly(4))
->method('doSomething')
->withConsecutive(...$args)
->willReturnOnConsecutiveCalls(...$results)
expects($this->exactly(N))
EntityName
+ Controller
, то есть для User это будет UserController
./**
* @Security("is_granted('ROLE_CAN_EDIT_USER')")
*/
class UserController extends EasyAdminController
Подробнее: item_permission
try {
// логика
} catch(\Throwable $e) {
// тут например логируем
// тут мы 3-м параметром для нового исключения добавили прошлое исключение
// чтобы не потерять стектрейс изначальной ошибки, мало ли откуда текущий код был вызван
// о чем и говорит PhpStan
throw new MyException('msg', 0, $e);
}
TelegramController ts = new TelegramController();
но обратил внимание что не инжектится репозиторий, точнее при отладке его значение равно Null
\Illuminate\Support\Facades\View::startPush('scripts', script('./path/to/script.js'));
$products = []; // ваш массив с товарами
/**
* Группирует любой массив массивов по любому полю $indexKey в качестве индекса
*/
function groupBy(array $input, string $indexKey): array
{
return array_reduce($input, function($res, $data) use ($indexKey){
if (!isset($data[$indexKey])) {
return $res;
}
$res[$data[$indexKey]][] = $data;
return $res;
}, []);
}
$groupedProducts = groupBy($products, 'catID');
// такое работает при условии, что категория с одним id будет иметь последнее название из найденных,
// то есть если id один, а название разные, то возможны не ожидаемые результаты
$categories = array_column($products, 'catName', 'catID');
foreach($groupedProducts as $catId => $catProducts) {
// тут доступно название категории $categories[$catId] и ее $catId
foreach($catProducts as $product) {
// тут выводим сами товары $product
}
}
Для PHP 5 нужно [] заменить на array(), предлагаю это сделать самому :)
$loader = new \Twig\Loader\ArrayLoader([
'you_name.html' => 'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
echo $twig->render('you_name.html', ['name' => 'Fabien']);