Задать вопрос
Пользователь пока ничего не рассказал о себе

Наибольший вклад в теги

Все теги (4)

Лучшие ответы пользователя

Все ответы (6)
  • Запрос mysql, как объединить сообщения в чаты?

    @alvi31182v
    GROUP BY GROUP_CONCAT для объединения сообщений в одну строку, упорядоченную по времени т.е если у тебя есть поле timestamp или msg_time если ты не хочешь использовать chat_id, то можно попробовать сделать следующий запрос

    GROUP BY chat_id - таким образом, строки с одинаковым chat_id будут объединены в одну группу

    "Функция LEAST выбирает минимальное из значений. Значениями могут выступать поля, а также строки и числа"
    "Функция GREATEST выбирает максимальное из значений / помогает упорядочивать пары пользователей"

    Комбинация LEAST и GREATEST гарантирует уникальность групировки чатов игнорируя порядок пар пользоваталей чатов.
    Вобщем есть набросок, дальше можно уже самому накидать и поиграться.
    $sql = "
        SELECT 
            MIN(from_user_id) as user1,
            MAX(from_user_id) as user2,
            chat_id,
            GROUP_CONCAT(msg ORDER BY msg_time) as messages
        FROM
            class_chat
        WHERE
            (from_user_id = :user1 AND to_user_id = :user2)
            OR
            (to_user_id = :user1 AND from_user_id = :user2)
            OR
            (from_user_id = :user3 AND to_user_id = :user4)
            OR
            (to_user_id = :user3 AND from_user_id = :user4)
        GROUP BY
            chat_id, LEAST(from_user_id, to_user_id), GREATEST(from_user_id, to_user_id)
    ";
    
    $stmt = $pdo->prepare($sql);
    
    $stmt->execute([
        ':user1' => 111, // тут айдишники пользаков
        ':user2' => 222,
        ':user3' => 333,
        ':user4' => 444,
    ]);
    
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        // Обработка результата
        echo "Chat ID: " . $row['chat_id'] . "\n";
        echo "User 1: " . $row['user1'] . "\n";
        echo "User 2: " . $row['user2'] . "\n";
        echo "Messages: " . $row['messages'] . "\n";
        echo "-----------------\n";
    }
    Ответ написан
    Комментировать
  • Как замокать и протестировать получение файла через 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);
        }
    }


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