Pull to refresh
90
0
Хайрулин Василий @Sirian

Разработчик

Send message

Ок. представь себе ситуацию - вот некая сущность UserBalance, у которой есть два метода - debit (пополнить средства) и credit (списать средства). Сущность валидирует себя, чтобы credit не позволил сделать баланс меньше нуля.

class UserBalance
{
    protected $currency;
    protected float $balance = 0;

    public function credit(float $amount)
    {
        if ($amount >= 0 && $amount < $this->balance) {
            $this->balance -= $amount;
        } else {
            throw new \Exception();
        }
    }

    public function debit(float $amount)
    {
        if ($amount >= 0) {
            $this->balance += $amount;
        } else {
            throw new \Exception();
        }
    }
}

class User {
     protected UserBalance $balance;
}

Потом приходит заказчик и говорит - нам нужно дать возможность для некоторых пользователей уходить в минус. мы их проссто пометим как privileged

class User {
    protected UserBalance $balance;
    protected bool $privileged;
}

Но вот незадача - класс UserBalance и знать не знает к какому пользователю он принадлежит. Как он теперь будет валидировать себя, чтобы позволить привилегированным пользователям уходить в минус?

А что касается валидации в целом - я придерживаюсь другой идеологии: сущность не должна заниматься валидацией. Например, откуда сущность может знать какие валюты поддерживает система? Что если есть разные лимиты на пополнение аккаунта в зависимости от валюты и от страны пользователя? Валидацией должны заниматься валидаторы, но не сущность)

Лучше проверить if ($amount >=0 && $amount <= $someMaxValue) { ... } else { throw ... }

someMaxValue может уберечь от миллионных потерь, в случае если где-то в коде случится баг (например при конвертации курса из-за деления на ноль). Живой пример - клиент webmoney для android

Валидировали-валидировали да невыдовалидировали. Проверка $amount <= 0 - частая ошибка что в PHP, что в JS. Встречайте - NAN

$a = new Account('1234567890123456');
$a->putMoney(NAN, 'USD');

Смотря что подразумевать под чистым контекстом. Тут как раз написано что будут отдельные cookie/cache и т.п.
Т.е. это как режим инкогнито (их может быть несколько)

Ощущение что статья написана каким-то джуном

1. Не используйте headless-браузер вообще

Никакой аргументации не приведено.

Почти всё, что может сделать браузер (кроме интерполирования и запуска JavaScript),

Так headless браузер как раз в основном и используют для сценариев с js

3. Ваш друг page.evaluate


Два приведенных кода сработают по разному. click() внтури evalute и click() через хендлер отличаются как минимум достоверностью события (event.isTrusted)

const puppeteer = require("puppeteer");
(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    page.on("console", (m) => console.log(m.text()));
    await page.evaluate(function () {
        const elem = this.document.documentElement;
        elem.addEventListener("click", e => console.log(e.isTrusted));
        elem.click();
    });
    const elem = await page.$('html');
    await elem.click();
    await browser.close();
})()


4. Распараллеливайте браузеры, а не веб-страницы

Вообще в апи puppeteer есть возможность создавать чистые контексты в
рамках одного запущенного браузера с помощью createIncognitoBrowserContext()
Это существенно дешевле, чем каждый раз запускать новый инстанс браузера
Ну так это же npm. Наверняка есть пакет negative-ten, поищи)

upd. немного промахнулся) Ответ был для VoldEx)
$response->setContent($image->getImage()->getFile()->getBytes());


Минус такого подхода, что файл цеилком грузится в память. Лучше использовать StreamedResponse и file->getResource()

new StreamedResponse(function () use ($file) {
    fpassthru($file->getResource());
})
Почему бы не использовать Symfony Console Component для написания команд?
К сожалению так будет тяжелее кастомизировать js опции.

А вообще я не сторонник загрузки скриптов в конце страницы, т.к. лично меня бесит например, когда страница уже отрисовалась, но из-за неподгруженных скриптов ничего на ней не работает. А тем более если на странице будут отображаться какие нибудь куски шаблонов, пока скрипты не подгрузятся)
Да, jquery и select2 в бандле не прилагаются, т.к. на разных проектах разные версии и сборки библиотек используются
Спасибо. Нет, именно document. Это как entity, только для DoctrineMongoDBBundle
Хотелось бы узнать больше про backend. Какой подход используете (callback или promise)? Какой шаблонизатор используете? Фреймворк самописный? Может отдельную статью напишете?
А хороших пакетов всего десятки…
Все равно не хватает синтаксического сахара для создания классов. хз когда реализуют
http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
например для $char_type, $node['type']
Используйте константы. Через месяц вы уже и сами не вспомните что за магия чисел происходит
console.log(navigator.userAgent);
navigator.__defineGetter__('userAgent', function(){return 'bla bla bla';})
console.log(navigator.userAgent);


п.с. аналогично можно и document.referrer подменять и т.п.
бритва оккама одним словом
В чем выигрыш то тогда, если логику из SymfonyClientController по выставлению заголовков (и т.п.) придется потом также переносить на другой фреймворк? на мой взгляд не то что выигрыша не будет — будет проигрыш
1
23 ...

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity