• Как настроить PHP Psalm в VS Code для вложенной папки?

    vhood
    @vhood
    Не забывайте отмечать решения
    "psalm.configPaths": [
        "src/psalm.xml",
    ]
    Ответ написан
    Комментировать
  • Как замокать и протестировать получение файла через fopen?

    @devian3000
    Можно пройтись хаком
    Создать обертку над протоколом https://www.php.net/manual/en/stream.streamwrapper..., зарегестрировать этот протокол https://www.php.net/manual/ru/function.stream-wrap...

    и вызов сделать что-то типо
    fopen("test://file1", 'r');

    должно сработать
    Ответ написан
    Комментировать
  • Как замокать и протестировать получение файла через fopen?

    @alvi31182v
    Нужно отметить что сам fopen это ведь встроенная функция в php и мокать её напрямую достаточно сложно,
    Для этого можно имплементировать типа FileReaderInterface и использовать DI.

    interface FileOpenerInterface {
        public function openFile($path, $mode);
    }
    
    final class FileOpener implements  FileOpenerInterface{
    public function openFile($path, $mode){
    return fopen($path, $mode);
    }
    }
    
    class FileProcessor{
    
     public function __construct(private FileOpenerInterface $fileOpener) { }
    
    public function readFileContent($filePath) {
            $fileHandle = $this->fileOpener->openFile($filePath, 'r');
            
            if ($fileHandle) {
                $content = fread($fileHandle, filesize($filePath));
                fclose($fileHandle);
                return $content;
            } else {
                return false;
            }
        }
    }
    
    class FileProcessorTest extends PHPUnit\Framework\TestCase {
    
        public function testReadFileContent() {
            // Создаем мок для FileOpenerInterface
            $fileOpenerMock = $this->createMock(FileOpenerInterface::class);
    
    
            $fileOpenerMock->expects($this->once())
                ->method('openFile')
                ->willReturn(fopen('php://memory', 'r'));
    
    
            $fileProcessor = new FileProcessor($fileOpenerMock);
            $content = $fileProcessor->readFileContent('fakefile://path/to/your/file.txt');
    
            // Проверяем ожидаемый результат
            $this->assertEquals("", $content);
        }
    }


    Сам этот тест я не зпускал но для понимания думаю пойдет, там дальше уже можешь сам что нибудь накидать, прикинуть что тебе нужно и т.д
    Ответ написан
    Комментировать
  • Какой способ хранения и выборки данных предпочтительней?

    @rPman
    Нужно разделять оптимизацию доступа к данным и их хранение.

    Да, выбирать конечно второй, но возможна ситуация, к примеру когда сбор аналитической информации по дням/неделям/месяцам/годам станет занимать значительное время а доступ к этой информации нужен частый, то разработчики вынуждены оперативно считать их хранить эти данные, дублируя их с исходными.

    Один из способов - считать агрегированную информацию в триггере на изменение и добавление данных.

    Поэтому ответ на твой вопрос может стать - первый вариант, но исходные данные хранить в неагрегированном виде в любом случае.
    Ответ написан
    Комментировать
  • Какой способ хранения и выборки данных предпочтительней?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Нужно делать одну таблицу и с ней работать. Самый простой вариант - обычно самый надежный и долговечный.

    Игры с разными таблицами - это овер-инжинеринг. И ты зря занимаешся этим потому что в топике совершенно
    нет мотивации к этому. Пускай одна таблица работает и если она по каким-то причинам перестанет справлятся
    - то тогда можно рассмотреть materialized views, витрины, гиперкубы и прочие технологии. Но пока это
    все - не нужно.
    Ответ написан
    Комментировать
  • Можно ли в redux toolkit передать параметр в middleware?

    @5465
    Да, в Redux Toolkit можно передавать параметры в middleware. Для этого можно определить middleware-функцию, которая возвращает другую функцию, которая уже принимает параметры.

    Например, для динамической передачи параметра в ваш logger middleware, вы можете определить функцию createLoggerMiddleware, которая будет принимать параметр someType и возвращать middleware-функцию, которая будет использовать этот параметр:

    export const createLoggerMiddleware = (someType: string): Middleware => {
      return () => next => action => {
        if (action.type === someType) {
          alert('blabla');
        }
        return next(action);
      };
    };


    Теперь в setupStore вы можете вызвать createLoggerMiddleware и передать нужный параметр:

    export const setupStore = () => configureStore({
      reducer: rootReducer,
      middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(createLoggerMiddleware('someType')),
    });


    Таким образом, вы сможете динамически настраивать middleware, когда они используются в разных приложениях.
    Ответ написан
    Комментировать
  • Почему в webpack module federation, при добавлении get параметра в url состояние redux сбрасывается?

    @5465
    Проблема может быть связана с тем, что при добавлении get параметра в URL компонент Dashboard перерендеривается и создается новый экземпляр Redux store для этого компонента, который не содержит сохраненных данных.

    Для решения этой проблемы необходимо сохранять состояние Redux store вне компонента и передавать его внутрь компонента при каждом рендере. Для этого можно использовать React Context API.

    В главном приложении создайте контекст:

    // appContext.js
    import React from 'react';
    
    export const AppContext = React.createContext({});


    В главном приложении оберните ваш компонент в провайдер контекста и передайте в контекст текущее состояние Redux store:

    // App.js
    import { AppContext } from './appContext';
    
    function App() {
      const [store, setStore] = useState(initialState); // начальное состояние Redux store
    
      return (
        <AppContext.Provider value={{ store, setStore }}>
          <Routes>
            <Route path='items' element={<Items />} />
          </Routes>
        </AppContext.Provider>
      );
    }


    В компоненте Dashboard микрофронта, вы можете получить текущее состояние Redux store через контекст и использовать его для отображения данных:

    // Dashboard.js
    import React, { useContext } from 'react';
    import { useSearchParams } from 'react-router-dom';
    import { AppContext } from '../appContext';
    
    function Dashboard() {
      const { store } = useContext(AppContext);
      const [searchParams] = useSearchParams();
    
      // получаем данные из текущего состояния Redux store
      const items = store.items;
    
      // обновляем данные в Redux store, если это необходимо
      if (searchParams.get('update')) {
        const newItems = await fetchItems(); // получаем новые данные
        setStore(prevState => ({ ...prevState, items: newItems })); // обновляем состояние Redux store
      }
    
      return (
        <div>
          {items.map(item => (
            <div key={item.id}>{item.name}</div>
          ))}
        </div>
      );
    }


    Теперь, когда вы добавляете параметр update в URL, компонент Dashboard не будет перерендериваться и состояние Redux store не будет сбрасываться, потому что вы сохраняете его в контексте.
    Ответ написан
    1 комментарий
  • Тесты Laravel, config() или env()?

    delphinpro
    @delphinpro Куратор тега Laravel
    frontend developer
    Всё что нужно знать про использование функции env()

    If you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files. Once the configuration has been cached, the .env file will not be loaded and all calls to the env function will return null.
    Ответ написан
    Комментировать
  • Тесты Laravel, config() или env()?

    TTATPuOT
    @TTATPuOT
    https://code.patriotovsky.ru/
    Используйте в основном коде и тестах только config().
    Это связано с тем, что у вас в приложении всегда должен быть только одни источник данных.

    Простой пример из дефолтной сборки Laravel. В app.php есть строка:
    'name' => env('APP_NAME', 'Laravel'),
    Самое просто, что вы можете сделать, это вызвать config('app.name') где-нибудь в коде, чтобы получить данные из этой настройки. Вот только если вы вызовите env('APP_NAME') вы, возможно, получите ошибку, в случае, если эта переменная не задана в переменных среды.
    Но как вы видите из кода выше, она совершенно необязательно должна быть задана в переменных среды, так как для неё задано значение по умолчанию: Laravel. А значения в конфиге могут быть вообще самой разной степени извращённости. И они могут составляться из частей. Например:
    'endpoint' => 'https://' . env('API_DOMAIN') . '/some/subroute',


    Это банальный и простой пример. Но на большой проекте с массой переменных и настроек вы однозначно столкнётесь с трудностями такого рода.

    Ваша задача сделать код удобным и читаемым. Чтобы будущие программисты могли распутать макаронину, что вы сплели. А разнообразие источников данных только запутает читателя.
    Ответ написан
    Комментировать
  • Тесты Laravel, использовать fixture или обычные массивы при внешнего тестировании API?

    JhaoDa
    @JhaoDa
    LaravelRUS Team
    Иногда одно, иногда другое, а иногда ещё хотим wiremock/wiremock...
    Ответ написан
    Комментировать
  • Актуальны ли правила из PSR-2 в PSR-12?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    PSR_12 extends PSR_2 {
    }
    Ответ написан
    Комментировать
  • Как называется плагин который выравнивает по оператору?

    delphinpro
    @delphinpro Куратор тега PhpStorm
    frontend developer
    6377411a8130d363716491.png
    Ответ написан
    Комментировать
  • Можно ли у динамического импорта поменять base url?

    Fragster
    @Fragster
    помогло? отметь решением!
    Ответ написан
    Комментировать
  • В чем разница обычного импорта и обращение с косой чертой?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Комментировать
  • Как тестировать миддлвары в которых используется конфиг?

    iMedved2009
    @iMedved2009
    Не люблю людей
    class TestSome{
        protected function setUp (): void
        {
            parent::setUp();
            Config::set("come_config.value", "blablabla");
        }
    }
    Ответ написан
    Комментировать
  • Некоторый вопрос о миграциях c enum Laravel. Что там не так?

    iMedved2009
    @iMedved2009
    Не люблю людей
    Правильно сказал. Через полгода у вас эту модель удалят. Или изменят. Придёт новый человек и попробует у себя развернуть проект и накатить миграции - получит ошибку. Как ее побороть? Искать в миллионе коммитов как эта модель выглядела?

    Правило общее для всех языков и фреймворков. В Гугл вбейте don’t use models in migrations получите ответ.
    Ответ написан
    Комментировать
  • Как отфильтровать сразу по нескольким динамическим полям?

    Например так.
    type FilterOptions<T> = {
      [K in keyof T]?: T[K] extends object ? FilterOptions<T[K]> : T[K];
    };
    
    const isOverlaps = <T>(entry: T, options: FilterOptions<T>): boolean => {
      const keys = Object.keys(options) as Array<keyof T>;
      
      return keys.every((key) => {
        if (typeof options[key] === 'object') {
          return isOverlaps(entry[key], options[key]!);
        }
    
        return entry[key] === options[key];
      });
    };
    
    const filterBy = <T>(collection: T[], options: FilterOptions<T>) => {
      return collection.filter((entry) => isOverlaps(entry, options));
    };
    Ответ написан
    2 комментария
  • Правильно ли рендерить вёрстку на сервере?

    gzhegow
    @gzhegow
    aka "ОбнимиБизнесмена"
    Позвольте поправить.

    Это не "правильно", это "возможно".

    Использование API уменьшает число данных в одном запросе, но заставляет вас делать авторизацию, делать всевозможные защиты. Если у вас есть фронтенд, который так и так делает запросы асинхронные (fetch/$.ajax), то разумнее конечно возвращать данные.

    С другой стороны, если ваш фронтенд не умеет в виртуальное дом-дерево (у вас не фреймворк, а нативный яваскрипт) - то при первой отдаче страницы в конце html вы можете отправить
    <template id="mytemplate"><div>{{data}}</div></template>
    , чтобы его схватить яваскриптом и генерировать верстку на основе него.

    Делать апи запрос, который возвращает html - это возможно, но это не то что "неправильно", это вы соединяете две задачи, каждая из которых может в будущем быть дополнена, в одну - и усложняете доработку в итоге. Если они по отдельности - доделать это проще. Апи запрос может быть использован где-то еще, если с версткой - то нет. Верстка же может быть изменена под новую тему оформления, если вместе - то сложнее.

    Считается, что доделывать должно быть легко, поэтому это "неправильно".

    Но вернуть верстку первым запросом когда человек только на сайт вошел - это нормальная практика и так было, пока было мало фронтенд фреймворков, в которых верстка вшивается в код самого фронтенда. Пока люди использовали handlebars/jquery это было нормально и вполне работало, а главное - не требовался специалист, который знает конкретный фреймворк, т.к. верстку знает большинство.
    Ответ написан
    Комментировать
  • Правильно ли рендерить вёрстку на сервере?

    @Kirill-Gorelov
    С ума с IT
    Я бы ответил так.

    Можно применить оба решения, и рендерить и возвращать сразу верстку, кстати, если ты посмотришь какой либо маркетплейс, то там они возвращают готовую верстку, просто вставляют ее в нужное место. И так же сделать через JS, отрисовывать нужный тебе виджет. У обоих решений есть и плюсы и минусы, нужно уметь в них разбираться и понимать какой из способов лучше подойдет именно тебе здесь и сейчас.
    Ответ написан
    Комментировать
  • Как тестировать запросы к API?

    lxsmkv
    @lxsmkv
    Test automation engineer
    Сначала нужно понять какую информацию мы пытаемся получить от теста, на какой вопрос он должен отвечать. Потом решаем необходимые границы охвата. Будет это приемочный / end-to-end тест, на работающем экземпляре приложения, либо это будет "сухой" юнит или интеграционный тест. Затем думаем как такой тест можно реализовать.

    Также стоит прикинуть, соразмерность затрат задаче. И понять, ту ли задачу мы хотим решить. Если говорят, что покрытие снизилось, может достаточно просто повысить покрытие, для чего может хватило бы, добиться того, чтобы тесты каким-то образом затрагивали код. Возможно к этому можно прийти более простыми способами.

    Когда ход действий ясен, приступаем к исследованию доступных подсказок. Тут все как обычно.
    Первое - смотрим как устроены остальные тесты на проекте, может там будет подсказка.
    Второе - смотрим раздел о тестировании той библиотеки или фреймворка который используется.
    Третье - беззастенчиво пользуемся опытом других людей с помощью поисковой машины. Думаю по запросу "Laravel API Testing" много чего можно будет найти. Или по запросу "PHP Mock Server"
    Ответ написан
    Комментировать