Ответы пользователя по тегу PHP
  • Как сделать serialize?

    copist
    @copist
    Empower people to give
    Всё дело в том, что в вашем примере 53, 55 и 56 - это должны быть строки. Надо принудительно приводить числа к строкам, чтобы 1:1 получить именно результат a:3:{i:0;s:2:"53";i:1;s:2:"55";i:2;s:2:"56";}
    <?php
        $a = array(
            0 => "53",
            1 => "55",
            2 => "56"
        );
    
        $b = serialize($a);
        echo $b; # a:3:{i:0;s:2:"53";i:1;s:2:"55";i:2;s:2:"56";}
    Ответ написан
    4 комментария
  • Как убрать повторяющиеся блоки с собесдником?

    copist
    @copist
    Empower people to give
    Возможно, это тестовый пример чата. Первая реализация.
    Что ты хотел показать в списке сообщений? Все сообщения, которые кто-то кому-то написал? Тогда он работает правильно. Счётчик только не используется и зачем то в таблице есть dialog_id, но ты его тоже не используешь, а вместо этого группируешь по from + to.

    Я бы для удобства визуально чат по-другому построил.
    Посмотри вот на такой мокап https://icons8.com/2015/07/17/icons8-wpf-ui-framework/, точнее вот этот экран take.ms/5F5rr
    С левой стороны список контактов, кому недавно писал ты или кто ответил тебе.
    Для его построения нужен такой запрос
    SELECT DISTINCT A.`user_id`
    FROM(
       SELECT m1.`from` as `user_id`, m1.`date` FROM `messages` m1 WHERE m1.`to` = 7
       UNION
       SELECT m2.`to` as `user_id`, m2.`date` FROM `messages` m2 WHERE m2.`from` = 7
       ORDER BY `date` DESC
    ) A

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

    Может быть это и много запросов в базу, но я был сделал их разными под каждый нужный элемент.
    Под список собеседников + счётчик сообщений - один запрос
    Если нужен счётчик непрочитанных сообщений, то второй запрос или серия запросов, хотя можно попробовать и в первый уместить.
    Под сообщения чата конкретного диалога - третий запрос.

    Как тестовый пример - норм. Вопросов нет.
    Если в пром эксплуатации, то хранить отдельные сообщения в реляционной базе накладно. Слишком много записей в таблицах. Желательно использовать NoSQL базу и хранить в одной записи базы один диалог целиком.
    Ответ написан
  • Почему переменная остается пустой, после присвоения ей значения в операторе switch?

    copist
    @copist
    Empower people to give
    Два замечания
    <?php
    $page = (isset($_GET['page'])) ? $_GET['page'] : 'index.php';
    
    $layoutModificator = '';
    
    // комментарий: определять значение $layoutModificator нужно до того, как она "эхается" в <body>
    switch ($page) {
    	case 'slider':
    		$includeFile = "page/slider.php";
    		break;
    	case 'animation':
    		$layoutModificator = "splash";
    		$includeFile = "page/animation.php";
    		break;
    }
    // комментарий: вот тут ниже пустая строка - потенциальная проблема, особенно при выдаче заголовков header(...);
    ?>
    <!-- .... -->
    <body class="<?php echo $layoutModificator;?>">
             <!-- .... -->
    				<?php include($includeFile); // вместо switch ?>


    Полный текст решения codepad.org/7dYnHaxp
    Ответ написан
    3 комментария
  • Как распарсить doc Обработать php и сохранить обратно?

    copist
    @copist
    Empower people to give
    Посмотри вот этот набор библиотек для работы с документами MS Office https://github.com/PHPOffice

    В частности PHPWord
    A pure PHP library for reading and writing word processing documents


    После изучения исходников и stackoverflow, могу сказать, что в PHP нельзя беспроблемно прочитать любой документ MS Word.

    На этом месте я предлагаю выдохнуть, выпить зелёного чая с мятой, накапать валерьянки.
    Далее придётся работать с C# или c макросами на Visual Basic for Office.
    Как-то так.
    Ответ написан
    5 комментариев
  • Как настроить сортировку типа 1-2-10-11 для массива в PHP?

    copist
    @copist
    Empower people to give
    Сортировка массивов в натуральном порядке значений из подмассивов с помощью uksort + strnatcmp()

    $unsortedArray = array(
        'import_files/5d/namers.jpg' => array('description' => '1 колечко блестящее'),
        'import_files/5d/name31.jpg' => array('description' => '10 морозное утро'),
        'import_files/5d/name13.jpg' => array('description' => '4 морозное утро'),
         // ...
    );
    uksort($unsortedArray, function($a, $b) use($unsortedArray) {
        return strnatcmp($unsortedArray[$a]['description'], $unsortedArray[$b]['description']);
    });


    Решение полностью codepad.org/2AaS37SE
    Ответ написан
    Комментировать
  • Как организовать взаимодействие между REST бэкендами?

    copist
    @copist
    Empower people to give
    Это называется SOA: сервисы, общающиеся между собой.

    Таким образом, например, посылается почта - один бакенд (твой сервер) передаёт соощение другому бакенду (почтовый сервер) по протоколу SMTP.
    Можно заливать файлы на другой сервер - протокол WebDAV, FTP или CSP.
    Твой сервер может постить твиты от имени другого пользователя - это делается через HTTP, при наличии токена авторизации. Запросы отправляются через curl или Guzzle.

    Но как это лучше делать если серверам нужны данные друг от друга? Обычные curl запросы?

    В общем, curl - это норм.
    Ответ написан
    2 комментария
  • Как получить GET параметры в MVC?

    copist
    @copist
    Empower people to give
    Позвольте всобачить сюда свой велосипед. Так сказать, самый сок.

    Пример разбора параметров $_GET:
    <?php
    class AppRequest {
    
    	protected $_get;
    
    	/**
    	 * Normalizes the request data
    	 * This method strips off slashes in request data if get_magic_quotes_gpc() returns true
    	 */
    	protected function normalizeRequest() {
    		if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
    			if(isset($_GET)) {
    				$_GET = $this->stripSlashes($_GET);
    			}
    		}
    		if(isset($_GET)) {
    			$this->_get = $_GET;
    		}
    	}
    
    	/**
    	 * Returns the named GET parameter value
    	 * If the GET parameter does not exist, the second parameter to this method will be returned
    	 * @param string $name the GET parameter name
    	 * @param mixed|null $default the default parameter value if the GET parameter does not exist
    	 * @return mixed|null the GET parameter value
    	 */
    	public function getQueryVar($name, $default = null) {
    		if (isset($this->_get[$name])) {
    			return $this->_get[$name];
    		}
    		return $default;
    	}
    
    	/**
    	 * Returns the request URI portion for the currently requested URL
    	 * @return string the request URI portion for the currently requested URL
    	 */
    	public function getRequestUri() {
    		static $requestUri;
    		if (!isset($requestUri)) {
    			if(isset($_SERVER['REQUEST_URI'])) {
    				$requestUri = $_SERVER['REQUEST_URI'];
    				if(!empty($_SERVER['HTTP_HOST'])) {
    					if(strpos($requestUri, $_SERVER['HTTP_HOST']) !== false) {
    						$requestUri = preg_replace('/^\w+:\/\/[^\/]+/', '', $requestUri);  // remove schema and host name "schema://host/"
    					}
    				} else {
    					$requestUri = preg_replace('/^(http|https):\/\/[^\/]+/i', '', $requestUri); // remove schema and host name "schema://host/"
    				}
    			}
    		}
    		return $requestUri;
    	}
    }

    весь код класса AppRequest

    Вариант логики разбора строки URL:
    Если есть какая-нибудь логика для коротких человеко-читаемых URL, то надо привести их к формату
    controller/action + все дополнительные параметры из URL перенести в переменные $_GET или завести для них отдельный специальный массив в класса AppRequest. Такое можно сделать путём статического разбора строки или регулярными выражениями.

    Пример:
    на вход / -> на выход home/index
    на вход /my-home-page/ -> на выход home/welcome
    на вход /photo/summer.jpg -> на выход gallery/view + $_GET['image-alias'] = 'summer.jpg'
    на вход /wiki/path/to/article.html -> на выход wiki/view + $_GET['page-alias'] = 'path/to/article'

    После этого преобразовать имя контроллера в имя класса, а имя действия - в метод (как в моём велосипеде).
    class HomeController {
        function indexAction() {
            echo "Welcome!";
        }
    }

    Полный пример разбора в классе AppRouter + файл конфигурации с правилами
    Пример правил для указанных выше 4х случаев:
    // Incoming URL mathing rules
    $rules = array(
    	// if request URI is empty
    	'' => array('home', 'index'), // -> код контролера + код действия
    
    	// if request URI looks like /my-home-page/ 
    	'/^my-home-page$/' => array('HomeController', 'indexAction'), // -> имя класса контроллера + имя функции
    
    	// if request URI looks like /photo/summer.jpg
    	'/^/photo/(?<alias>.+)$/' => array('gallery', 'view', array('image-alias' => ':alias')),
    
    	// if request URI looks like /wiki/path/to/article.html
    	'^/wiki/(?<alias>.+)\.html$' => array('wiki', 'view', array('page-alias' => ':alias')),
    );


    А можно поменять роутинг так, чтобы под каждое действие был отдельный класс
    class HomeIndex {
        function run() {
            return new AppResponse("Welcome!");
        }
    }

    В некоторых микро-фреймворках можно даже функции назначать
    function home_index() {
        return new AppResponse("Welcome!");
    }
    $routes = array(
        '/my-home-page/' => 'home_index',
    );

    И даже использовать анонимные функции, тогда у них вся логика приложения вообще в один конфигурационный файл вмещается
    $routes = array(
        '/my-home-page/' => function() { return new AppResponse("Welcome!"); },
    );
    Ответ написан
    Комментировать
  • Почему не прокатывает авторизация?

    copist
    @copist
    Empower people to give
    Надо посмотреть что ещё сообщает cUrl после завершения запроса.

    $result = curl_exec($curl);
    $info = curl_getinfo($curl);
    $error = curl_error($curl);
    echo "result: "; var_dump($result);
    echo "info: "; var_dump($info);
    echo "error: "; var_dump($error);
    Ответ написан
  • Ошибка на сайте (писался на php) umenie.php:573 Uncaught ReferenceError: hideshow is not definedonmouseout @ umenie.php:573, в чем дело?

    copist
    @copist
    Empower people to give
    Картинки нет.
    У вас ошибка в Javascript.
    Проверьте, что к странице подключились все файлы javascript
    Ответ написан
    Комментировать
  • Как создать конструктор для сайта?

    copist
    @copist
    Empower people to give
    Вариант 1. Нарисовать здание со всеми вообще конструкционными элементами в векторном графическом редакторе, который умеет экспортировать картинки в формате SVG, отдельным элементам проставить идентификаторы. Пример установки идентификатора элемента в изображении SVG через Inkscape take.ms/0lpl8
    Затем вставить файл SVG в HTML и с помощью Javascript включать/выключать некоторые кривые в такой картинке. Пример: take.ms/dhNfG
    Рабочий пример на Codepen codepen.io/copist/pen/WvVRRL

    Вариант 2. Сделать много мелких картинок PNG для отдельных элементов и из таких картинок собирать большую картинку как пазл: крыша#1 + стены#2 + окна#3 опять же с помощью Javascript
    Вариант 3. Реализовать отрисовку через Canvas
    Вариант 4. Запрограммировать по тому же принципу, что и SVG, но на Flash
    Вариант 5. И ещё есть Silverlight
    Ответ написан
    Комментировать
  • Каким алгоритмом (функцией PHP) лучше получить хэш строки для последующего сравнения по базе данных?

    copist
    @copist
    Empower people to give
    sha1 - там коллизий меньше, вычисляется не намного дольше md5, длина 40 байт

    Активно используется в протоколе BitTorrent и Git
    Ответ написан
    Комментировать
  • Что подразумевается под маленьким, небольшим, крупным проектом на PHP?

    copist
    @copist
    Empower people to give
    Зависит от количества технологий, которыми придётся воспользоваться для его реализации.
    Я сейчас сам себе условно поставлю задания на разработку проектов 4х уровней сложности.

    Простейший сайт-визитка.
    Технологии:
    1. Дизайн: типовой, картинки со стоков или вообще нет, всего несколько страниц
    2. Реализация: HTML, CSS, может быть JS
    3. Средства разработки: очень простые, вплоть до notepad.exe
    4. Хостинг: бесплатный shared hosting
    5. Обновление: вручную, по FTP
    Интернет-магазин средней сложности
    1. Дизайн: заказной, картинки, цены и описание конкретных товаров
    2. Реализация: HTML, CSS, JS, серверный язык программирования, база данных, кэширование. Возможно, интеграция с внешними системами, например, 1С, платёжные системы или доставка. В качестве базового решения использовать готовое, типа OpenCart
    3. Многопользовательский режим: несколько редакторов, посетители сайта, покупатели
    4. Средства разработки: графический пакет, IDE, клиентское приложение для базы данных
    5. Хостинг: платный shared или virtual dedicated
    6. Обновление: вручную
    Информационный портал повышенной сложности
    1. Дизайн: заказной, штатный дизайнер, художник, фотограф
    2. Реализация: CSS/SCSS/LESS, сложный Javascript c фреймворками типа Angular, несколько серверных языков программирования, база данных с горизонтальным и вертикальным массштабированием, дублированием, распределённая файловая система, кэшированием, очереди заданий, фоновые задачи.
    3. Многопользовательский режим: любой может добавлять статьи с мульти-медиа контентом, многопользователькие чаты realtime, внутренняя система сообщений
    4. Средства разработки: графический пакет, IDE, клиентское приложение для базы данных, репозиторий кода
    5. Хостинг: virtual dedicated или dedicated + тестовый и демонстрационный сервера меньшей мощности + резервный + балансировка нагрузки
    6. Сервис поддержки пользователей, модерация статей и чатов
    7. Почтовые рассылки, подписки на отдельные темы или авторов, внутренняя система сообщений с дублированием на электронную почту
    8. Авто-тесты
    9. Обновление: автоматическое, через Chef, Capistrano или иной способ
    Запредельно сложный сервис
    1. Дизайн: уникальный, специальный, заказной, несколько штатных дизайнеров, все непрерывно работают над улучшением и разрабокой новых возможностей
    2. Реализация: Reach Client Application, передовые клиентские технологии, реализация многопользовательского онлайн 3D мира, несколько серверных языков программирования, несколько типов баз данных с горизонтальным и вертикальным масштабированием, дублированием, кэшированием, очереди заданий, фоновые задачи; части системы общаются между собой по разным протоколам и асинхронно
    3. Многопользовательский режим: международный сервис, количество пользователей просто зашкаливает, они работают круглосуточно, нет периода однозначного снижения нагрузки на сервер для технического обслуживания
    4. Специфический фукционал: пользователи могут совместно делать необычные вещи, например, конструировать и выпускать реальные автомобили онлайн
    5. Средства разработки: чего только не используешь, лишь бы разобраться в коде и документации, который состоит из множества кусков и зависимостей, на разных диалектах разных версий языков, ежедневно изменяемый сотней программистов, тестовые сервера под каждую отдельную фичу; в разработке сразу несколько фич, и они конфликтуют между собой
    6. Хостинг: облачные сервера, много-много серверов, под все части системы резервирование, свой датацентр, свой оптоволоконный канал связи
    7. Авто-тесты, мониторинг, метрики, системы оповещения о сбоях и автоматического устранения аварий
    8. Резервные источники энергии, своя электростанция
    9. Круглосуточный сервис поддержки пользователей
    10. Управление персоналом: администраторы, электрики, программисты разной специализации, менеджеры, маркетологи, аналитики, тестировщики, бухгалтерия, отдел персонала, психолог, стоматолог, поликлиника, столовая, ресторан, фитнес-зал, спорт-комплекс, автопарк
    11. Внутрисистемная виртуальная валюта, возможность взаиморасчётов, найм, покупки
    12. Холдинг: подчинённые компании различных отраслей и сфер экономики или фирм, расположенные в различных регионах, с общей информационной системой
    13. Почтовые рассылки на миллионы подписчиков
    14. Мультиплатформенность: под разные операционные системы отдельная версия программного продукта
    15. Обновление: автоматическое, с бакапами до и после, авто-восстановлением при неудачном обновлении, специфическая система обновления; у каждой версии или модуля своя логика обновления; распределённое одновременное обновление большого количества серверов


    Что из этого Гугль? Ничего. Он зашкаливает по сложности.
    Ответ написан
    1 комментарий
  • Как привязать сессию к пользователю?

    copist
    @copist
    Empower people to give
    Используйте memcached - этот сервис хранит данные в памяти и удаляет неиспользуемые.
    Если в сессии есть данные, которые нужно хранить постоянно, дублируйте запись в базу данных и в memcached.
    Если у пользователя кука ещё жива, а сессия на сервере уже удалилась, запросите её из базы и опять сохраните в кэш.
    Вот приблизительно так: cdraw?lz=dGl0bGUgINCg0LDQsdC-0YLQsCDRgSD
    Ответ написан
    Комментировать
  • Почему пропадают куки после перезагрузки страницы?

    copist
    @copist
    Empower people to give
    мануал: setcookie

    сигнатура:
    bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )

    Я бы ещё указал параметры путь $path='/' и домен $domain='какой-надо.ru'
    Ответ написан
    Комментировать
  • Почему приходит неполная станица при иcпользовании curl + proxy?

    copist
    @copist
    Empower people to give
    У вас есть доступ к самому прокси?
    Проверьте, может ли ваш прокси писать в папку с временными файлами.
    Ответ написан
  • Что делать дальше?

    copist
    @copist
    Empower people to give
    Собирай опыт сам в том, к чему душа тянется.
    Ответ написан
    Комментировать
  • Как командно разрабатывать php проект?

    copist
    @copist
    Empower people to give
    Инфраструктура
    * Создайте репозиторий на Bitbucket или GitHub.
    * Создайте себе локально копию репозитория и локально поднимите базу данных с одинаковой структурой
    * Если в базе требуются изменения, создавайте "миграции", которые обновят структуру данных или сами данные.
    * Свои изменения по коду, так же как и миграции, отправляйте в репозиторий

    Ещё есть возможность создания виртуальных серверов для разработки или использование online IDE. Решает кучу проблем, если интернет быстрый.
    * https://compilr.com/ Полноценная среда разработки
    * https://koding.com/ Среда разработки с предустановленным веб-сервером и элементами социальной сети
    * online-php.com Online IDE
    * https://codeanywhere.com/ Среда разработки. Код можно хранить в облаке, а также в Dropbox, Google Drive, FTP, github.
    Другие тулзы для совместной работы в online

    Промежуточные версии
    Если вы географически недалеко друг от друга, то просто периодически показывайте, что у вас получается.
    Если нет, пользуйтесь Skype Shared Screen, Join.me и другие аналогичные продукты, чтобы вместе смотреть и обсуждать голосом. А лучше TeamViewer, чтобы можно было вместе и посмотреть, и поправить.

    Обновление сервера
    Изменения на сервер устанавливайте из того-же репозитория. Не забудьте про миграции. Озаботьтесь вопросами безопасности. Хотя бы так: скрыть файлы .git
    Ответ написан
    Комментировать
  • Отправка JSON'a через XHR с помощью POST-метода - как принимать и парсить?

    copist
    @copist
    Empower people to give
    stackoverflow.com/a/8945912

    $entityBody = file_get_contents('php://input');
    Ответ написан
    Комментировать
  • Как выполннить большой скрипт php через ajax?

    copist
    @copist
    Empower people to give
    А. Экономь память
    1. Храни как можно меньше данных в памяти. Запросы в БД делай через курсоры, чтобы извлекалось меньше записей. Не используй жадные выборки без перечисления полей (SELECT *) особенно если в запросе есть JOIN.
    2. Не храни в памяти сырые данные. Копи суммы по каждой записи, веди счётчики где надо, вычисляй функции, даже формируй HTML по мере чтения, но целиком выборку в память не собирай.
    Б. Используй очереди (RabbitMQ и другие) для реализации асинхронности, чтобы браузер не ждал бесконечно ответа. Ответ запрашивай отдельным запросом
    В. ... или сделай сервер Comet и пусть PHP сам выдаст результат, когда закончит работу
    Ответ написан
    Комментировать