PHP
330
Вклад в тег
<?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));
$qb->expr()->andX(
$qb->expr()->andX(
$qb->expr()->isInstanceOf('sub1', 'TargetClass'),
$qb->expr()->eq('sub1.sub1Field', $sub1FieldValue)
)
);/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"cat" = "Cat", "dog" = "Dog"})
*
* @ORM\Entity(repositoryClass="AnimalRepository")
*/
class Animal
{
/**
* @ORM\Id
* @ORM\Column(type="integer", nullable=true)
* @ORM\GeneratedValue(strategy="AUTO")
*/
public ?string $id = null;
}
/** @ORM\Entity */
class Cat extends Animal
{
/**
* @ORM\Column(type="string")
*/
public $meow;
}
/** @ORM\Entity */
class Dog extends Animal
{
/**
* @ORM\Column(type="string")
*/
public $woof;
}class AnimalRepository extends EntityRepository
{
/**
* @param array $filters
*
* @return \Generator<Animal::class>|Animal[]
*/
public function filter(array $filters): \Generator
{
foreach ($filters as $filter) {
[$entityClass, $conditions] = $filter;
if (!is_a($entityClass, Animal::class, true)) {
throw new \LogicException('Класс должен быть ребенком ' . Animal::class);
}
yield from $this->getSubEntities($entityClass, [$conditions]);
}
}
private function getSubEntities(string $subEntityClassName, array $conditions): \Generator
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('e')->from($subEntityClassName, 'e');
foreach ($conditions as $condition) {
[$param, $paramValue] = $condition;
$qb
->andWhere("e.$param = :$param")
->setParameter($param, $paramValue);
}
foreach ($qb->getQuery()->getResult() as $entity) {
yield $entity;
}
}
}class AnimalRepositoryCest
{
/** @var EntityManagerInterface */
private $em;
public function _before(FunctionalTester $I): void
{
$this->em = $I->grabService('doctrine.orm.entity_manager');
}
public function testSuccessFilter(): void
{
$cat1 = new Cat();
$cat1->meow = 'meow1';
$cat2 = new Cat();
$cat2->meow = 'meow2';
$dog1 = new Dog();
$dog1->woof = 'woof1';
$dog2 = new Dog();
$dog2->woof = 'woof2';
$this->em->persist($cat1);
$this->em->persist($cat2);
$this->em->persist($dog1);
$this->em->persist($dog2);
$this->em->flush();
/** @var AnimalRepository $animalRepository */
$animalRepository = $this->em->getRepository(Animal::class);
assertInstanceOf(AnimalRepository::class, $animalRepository);
// этот код можно в репозитории сокрыть
$resultIter = $animalRepository->filter([
Cat::class, [['meow' => 'meow2']], // тут точка расширения гибкости добавления условий, чтобы все не только eq() было
Dog::class, [['woof' => 'woof1']],
]);
$result = iterator_to_array($resultIter);
assertCount(2, $result);
assertInstanceOf(Cat::class, $result[0]);
assertSame('meow2', $result[0]->meow);
assertInstanceOf(Dog::class, $result[1]);
assertSame('woof1', $result[1]->woof);
}
}
class Relay
{
private $privateProperty;
public function __construct()
{
$this->privateProperty = new \stdClass();
}
// метод, который работает с приватным свойством
public function call()
{
return $this->privateProperty;
}
}use PHPUnit\Framework\TestCase;
class RelayTest extends TestCase
{
public function testCall(): void
{
$reflectionClass = new \ReflectionClass(Relay::class);
$reflectionProperty = $reflectionClass->getProperty('privateProperty');
$reflectionProperty->setAccessible(true);
// создаем наш объект БЕЗ конструктора
$relay = $reflectionClass->newInstanceWithoutConstructor();
// Меняем свойство и вызываем метод, работающий с этим приватным полем
$reflectionProperty->setValue($relay, 1111);
self::assertEquals(1111, $relay->call());
// Меняем свойство и вызываем метод, работающий с этим приватным полем
$reflectionProperty->setValue($relay, 'aaaa');
self::assertEquals('aaaa', $relay->call());
}
}class RelayTest extends TestCase
public function testCall(): void
{
/** @var Example $stub */
$stub = Stub::make(Relay::class, [
'privateProperty' => 1111,
]);
self::assertEquals(1111, $stub->call());
$stub = Stub::make(Relay::class, [
'privateProperty' => 'aaaa',
]);
self::assertEquals('aaaa', $stub->call());
}
}
UserProvider userProvider = new UserProviderAggregate(
new LoggerUserProviderDecorator(
new CacheUserProviderDecorator(
new UserProvider(...)
new Cache(),
),
new Logger(),
),
new DummyUserProvider()
)public function loadUsers(): Collection<User> {
return new Collection<User>(...);
}public function loadUsers(): Collection<User> {
if(cache.has('cache_users_key')) {
return cache.get('cache_users_key');
}
Collection<User> users = new Collection<User>(...)
cache.put('cache_users_key', users)
return users;
}public function loadUsers(): Collection<User> {
if(...any condition) {
return dbUsers.loadUsers();
}
if(...any condition) {
return dummyUsers.loadUsers();
}
throw new Exception();
}