нужно проверять доменный адрес его почты
Не будет ли большой нагрузки на базу данных при переборе значений?
<?php
function cutMenuTitle(array $elements, string $elementKey = 'item', int $limit = 15) {
return array_map(function($item) use ($elementKey, $limit) {
if (!isset($item[$elementKey])) {
return NULL;
}
if (mb_strlen($item[$elementKey]) > $limit) {
return mb_substr($item[$elementKey], 0, $limit - 3) . '…';
}
return $item[$elementKey];
}, $elements);
}
$menu = [
['item' => 'Заголовок1 длинный'],
['item' => 'Заголовок2'],
];
var_dump(cutMenuTitle($menu, 'item', 13));
// [
// "Заголовок1…",
// "Заголовок2",
// ]
<?php
$generator = (function (): \Generator {
yield 1;
yield 2;
})()
var_dump($generator->current());
$generator->next();
var_dump($generator->current());
if($error === null){}
предпочтительный (иногда он обязательный по стандартам), тк вариант if(!$error){}
— это авто-приведение к bool:!$any
можно использовать комфортно, когда вы (и программа) уверена, что работает либо с объектом, либо с bool 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) {
// обработка
}
<?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))
$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']);
class Dog extends Animal{}
class Penguin extends Animal{}
$allAnswers = [
1 => [2,3,4,5], // верный, тк даны только верные ответы
2 => [7,8,9,52], // не верный, дан неверный 52
3 => [10,11,12,25], // не верный, дан неверный 25
4 => [13], // не верный, тк пропущены верные ответы 14 и 15
];
$dbAnswers = [
// данные из БД
];
/**
* Группирует любой массив по любому полю $indexKey в качестве индекса,
* и $columnKey в качестве группируемых значений
*/
function groupBy(array $input, string $indexKey, string $columnKey): array
{
return array_reduce($input, function($res, $data) use ($indexKey, $columnKey){
if (!isset($data[$indexKey], $data[$columnKey])) {
return $res;
}
$res[$data[$indexKey]][] = $data[$columnKey];
return $res;
}, []);
}
/**
* Маппинг введенных ответов с верными ответами по каждому вопросу
*/
function computeAnswersResult(array $inputAnswers, array $questionsWithCorrectAnswers): array
{
$correctAnswers = $questionsWithCorrectAnswers[$questIn] ?? [];
$result = [];
foreach($inputAnswers as $questIn => $answesrIn) {
$errors = array_diff($answesrIn, $correctAnswers);
$corrects = array_diff($answesrIn, $errors); // если бы не нужно было выводить, то код сильно бы сократился
$correctDiff = array_diff($correctAnswers, $corrects);
// Если нет лишних ответов и число введенных верных ответов
// совпадает с числом верных в БД, то статус положительный
$completed = \count($errors) === 0 && \count($correctDiff) === 0;
$result[$questIn] = [
'errors' => $errors,
'corrects' => $corrects,
'completed' => $completed,
];
}
return $result;
}
// Группируем верные ответы по каждому вопросу
$questionsWithCorrectAnswers = groupBy($dbAnswers, 'id_question', 'id');
// Маппим введенные ответы на правильные и получаем результат
$result = computeAnswersResult($allAnswers, $questionsWithCorrectAnswers);
// Посчитаем успешные
$completedCount = \count(
array_filter($result, function($answer) {
return $answer['completed'] ?? false;
})
);
// ОТОБРАЖЕНИЕ
$html = '';
foreach ($result as $questId => $details) {
$status = $details['completed'] ? 'верный' : 'не верный';
$html .= 'Вопрос №:' . $questId . PHP_EOL;
$html .= 'Правильные ответы: ' . implode(', ', $details['corrects']) . PHP_EOL;
$html .= 'Результат вопроса: ' . $status . PHP_EOL;
$html .= '-------------------' . PHP_EOL;
}
$html .= 'Всего верных: ' . $completedCount;
echo $html;
// Arrange
$provider = $this
->getMockBuilder(UserProvider::class)
->setMethodsExcept(['delete']) // перечисленные тут методы будут настоящими, хоть и мок
->setConstructorArgs([]) // сюда зависимости конструктора передать
->getMock();
$provider = $provider
->expects($this->once())
->method('canDelete') // мокаем приватный метод
->willReturn(true);
// Action
$result = $provider->delete();
// Assert
$this->assertEquals(true, $result);
location / {
try_files $uri /index.php?$args;
}
location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^/first/?$ first.php;
rewrite ^/second/?$ second.php;
rewrite ^ /index.php;
}
/** @return MemberEntity[] */
public function getMembers() {}