Ответы пользователя по тегу PHP
  • Как привести переменную к переменному типу?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    В других языках ЭТО реализуется так, как этого требует система типов конкретного языка, с помошью плюшек, предоставляемых самим языком и/или его стандартной библиотекой :) Подробности (например): раз, два, три. На практике это может быть что угодно - от велосипедной эксплуатации автобоксинга или перегрузки операторов / сигнатур методов, через рефлексию, дженерики, темплейты (в плюсах), или оберточные типы (как в Java) и вплоть до реальной компиляции "на лету" в каком-нить Groovy. Последнее, семантически - тот же eval, чреватый теми же побочными эффектами.

    Тут фантазия разработчика, владеющего конкретным языком, ограничена, разве что, здравым смыслом, который, в первую очередь, призывает задуматься, а нафига это вообще нужно :) И, что характерно: в подавляющем большинстве случаев (если, конечно, мы не пишем како-нибудь интерпретатор или полиморфный вирус) эти размышления приводят к тому, что все решается проще и надежнее именно статической типизацией... т.е. да - где-то таки придется написать switch case :)
    Ответ написан
    Комментировать
  • Как разобраться в этой терминологии?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Благодаря тому, что программирование, это не идеология, не мифология, а вполне себе прекладная научная дисциплина, вся терминология в нем изначально предельно точная и информативная. В любом термине (кроме некоторых маркетинговых мемов) обычно содержится почти полный ответ на вопрос: "а что это такое", для понимания которого не нужно ничего запоминать - достаточно анализировать слова и синтезировать смысл абстракции по аналогии с предметами реального мира :) Однако, есть два момента.

    Первый: терминология исторически англоязычная и всяческие попытки переводов чаще вредят, чем помогают понять суть. (Мне, например, пришлось напрячь Гугл, чтоб удостовериться, что под "шлюзом" Вы действительно подразумеваете "pattern gateway", а не что-то там еще).
    Второй: термины часто обозначают не конкретные сущности, а абстракции. (Если вдруг значения последних двух слов понятны только на уровне смутного ощущения, разберитесь, что они конкретно означают... абстракция - это не "нечто туманное и заумное", а совсем другое :) ) Соответственно, для толкования этих терминов нужно использовать абстрактное мышление. Как?

    Например, для того же шлюза... шлюз бывает между двумя реками с разным уровнем... да, там есть выше - ниже. Однако, бывает между двумя отсеками космического корабля (хорошо - там все еще может быть разное давление), а бывает между толпой пассажиров в аэропорту и выходом к самолету (давление толпы?)... или, между локальной сетью и внешней, и т.д. Если задуматься, почему все это называют таким словом, легко понять, что суть понятия не столько в перепаде (уровней, давлений и т.д.), а, наверное, в том, что "это такое нечто, только через которое можно попасть/выйти из одного в другое". .. оно же, кстати, соответствует буквальному переводу слова "gateway" - "выход наружу"...

    И - сюрприз(!) - именно в этом и заключается суть паттерна. А вот, для сравнения, его формальное определение: "Объект, который инкапсулирует доступ к внешней системе и ресурсу." Решайте для себя сами, что лучше - знать английский, запоминать такие определения или один раз понять смысл аналогии, только учтите, что у всех слов в определениях тоже есть совершенно конкретный, точный смысл, который нужно знать или уметь находить - иначе определение ничего не объяснит, а только еще больше запутает :)

    Далее... как его "сделать в коде"? А фиг его знает! Как удобнее для проектируемой системы, так и делайте. Может, это будет один класс, может микросервис, а может вообще железяка на FPGA. Паттерн не дает никаких готовых рецептов (типа, взять три грузовика бетона, выкопать яму глубиной 5 метров и пр.) - он просто говорит, что чем всем частям системы "лазить наружу" как попало, лучше это дело сконцентрировать в одном месте. И, кстати, патерн не является "современным стандартом" и, вообще, стандартом! Это просто обобщенный опыт поколений разработчиков систем. Не более, чем соображение мыть руки перед едой... если зачем-то нужно, можно и не мыть, но если нет какой-то осознанной мотивации, то мыть в большинстве случаев - лучше :)

    Идем дальше... интерфейс. Что это такое? Формочка с кнопочками и чекбоксиками? А может, разъем USB? А может, код на каком-нибудь ЯП? Что между всем этим общего? Да очень просто! Интерфейс, это набор правил и соглашений о том, как пользоваться какими-то функциями того, что предоставляет этот интерфейс :)

    Вот и все! В ИТ-шной терминологии нет никакой магии и никакого сакрального смысла. Для понимания достаточно знать ТОЧНОЕ значение довольно небольшого количества слов и для любого непонятного термина всегда задавать два простых вопроса: "что это значит" и "почему", и находить на них ответы. И все туманное и странное быстро становится простым и понятным :)
    Ответ написан
    2 комментария
  • Цикл с таймаутом ровно в 1 секунду?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Ваш вопрос можно приводить в качестве наглядного пособия на тему "Как именно вылазит боком кривая архитектура системы" :) Основная проблема в том, что интеграция компонент через storage есть зло, рано или поздно (чаще - рано) заставляющее разработчика выполнять стойку на ушах. Так что, если есть такая возможность, постарайтесь устранить зло в корне, т.е. найти способ узнавать об изменениях, ну, или хотя бы о самом факте, до того, а не после. Тогда не придется ничего опрашивать в цикле, а только реагировать на изменения. А это уже - половина проблемы!

    Если возможности нет, а делать все равно надо, сначала смитритесь с тем, что Вы никогда на PHP не добьетесь ровненько 86400 вызовов в сутки каждую секунду, если только не поставите ядро реального времени / не напишете соответствующий код на С и т.д. и т.п. Особенно, если storage крутится на том же процессоре в той же ОС, и количесво данных в нем будет со временем увеличиваться. Но это почти наверняка и не нужно, а нужно проанализировать задачу и понять, что на самом деле критично и какие отклонения от идеала возможны без ущерба для функциональности.

    "Примерно 0.03с" само по себе еще не о чем не говорит. Это всегда или в случае, если изменений нет, или если они небольшого объема? А если 90% данных обновились? Это - раз. Два: если изменения обнаружены, сколько может занять их обработка (в худшем случае)?.. И, наконец, три: если уже наступила "следующая секунда", а мы все еще не закончили обработку прошлых изменений, возникает целый ряд вопросов. Имеет ли в этом случае вообще смысл проверять новые изменения (сможем ли мы их осмысленно обработать, если найдем)? Если да, понадобится как минимум 2 потока. Если нет, насколько критично пропустить эту секунду? А сколько еще можно пропустить без ущерба для функционала? Предположим, это не критично, и мы уже пропустили секунду (или несколько), что нам важнее: чтоб следующая проверка выполнилась как можно ближе к границе "следующей секунды", или как можно быстрее? И т.д. и т.п.

    Не зная ответов на эти и подобные вопросы, невозможно предложить "правильное" решение. Но в качестве сферического коня в вакууме можно посоветовать бесконечный цикл, в котором выполняется проверка, реакция на найденные изменения, после чего вычисляется время до следующей проверки, на которое выполняется sleep().
    Ответ написан
    Комментировать
  • Документация к SOAP API. Нужна ли она и справедливо ли возражение о том, что WSDL достаточно?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Послать такого менеджера нужно на... курсы по WSDL, в частности, чтоб про "wsdl:documentation" узнал и устыдился. А вообще, типы параметров, определенные WSDL - это, как бы, одно, а вот их предназначение - совсем другое. Уважающие себя разрабы ко второму не только пишут доку в WSDL, но могут даже нарисовать UML и написать текст с примерами, если логика интерфейса требует этого ввиду своей нетривиальности.

    P.S. Впрочем, самоуважение, как и профессионализм, не относятся к ключевым скилам среднестатистического современного менеджера :)
    Ответ написан
    Комментировать
  • Пытаюсь сделать превью для изображения. Можете помочь?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Левой пяткой через правое ухо, я бы сделал как-то так (для наглядности результат сохраняется в файл):
    $src = './orig.jpg';
    $trg = './thumb.jpg';
    
    cropAndResize2Square($src, 128, $trg);
    
    function cropAndResize2Square($originalPath, $targetSquareSide, $targetPath){
    
    	//get original's dimension
    	list($origW, $origH) = getimagesize($originalPath);
    
    	//create images
    	$srcImg = imagecreatefromjpeg($originalPath);
    	$trgImg = imagecreatetruecolor($targetSquareSide, $targetSquareSide);
    	
    	//calculate source square position and side
    	if($origW >= $origH){
    		$srcSquareSide = $origH;
    		$srcSquareX    = ($origW - $targetSquareSide) / 2;
    		$srcSquareY    = 0;
    	} else {
    		$srcSquareSide = $origW;
    		$srcSquareX    = 0;
    		$srcSquareY    = ($origH - $targetSquareSide) / 2;
    	}
    	
    	imagecopyresampled($trgImg, $srcImg, 
    			0, 0, $srcSquareX, $srcSquareY, 
    			$targetSquareSide, $targetSquareSide, $srcSquareSide, $srcSquareSide);
    
    	//encode and save result (default quality 75%)
    	imagejpeg($trgImg, $targetPath);
    	
    	//clean up
    	imagedestroy($srcImg);
    	imagedestroy($trgImg);
    }

    P.S. Если понадобится фильтр (например, Ланчос), лучше юзать ImageMagic. Хотя, если бешенной собаке семь верст - не крюк, можно написать и ручками. Но на PHP это будет убийственно медленно :)
    Ответ написан
    1 комментарий
  • Как сделать квадратное превью изображения на PHP?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Например, воспользоваться imagecopyresampled().

    Для предварительного определения размеров оригинала (и дальнейшего нахождения максимальной квадратной области) можно воспользоваться getimagesize().

    Всех делов кругом бегом - 10~15 строк кода :)
    Ответ написан
    4 комментария
  • Чем отличается junior от middle? а Senior?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Вот как это выглядит с т.з. работодателя

    Джун
    - собеседование
    изъясняется исключительно на сленге (большую часть которого не может внятно объяснить), готов в одиночку за неделю написать новую ОС, или две - за полторы, если только для этого не придется учить ассемблер, несмотря на юный возраст уже обладатель прав на обе версии и один бэкап личного сайта с фотографией кошки в розовой рамке и знает, что синглтон - это абсолютное зло, хотя и не может написать его без ошибок.
    - испытательный срок
    долго мудохается с настройками рабочего места, которые регулярно слетают под тяжестью многотысячных плагинов, шелов и скринсейверов, донимает админов, находит две (орфографические) ошибки в документации проекта и один быстрый альтернативный способ сделать форк из SVN, после которого проект, к сожалению, не билдится не только у него, но и у всей команды. Берется все немедленно исправить с помощью другого чудотворного плагина, (неожиданный баг в котором приходится фиксить двум миддлам), после чего насильственно лишается рута, плагинов и шелов и начинает изучать проект под чутким контролем матерящихся миддлов.
    - работа
    научился билдить проект, писать тесты и коммитить, не роняя этим билд, понял смысл многих сленговых выражений, подружился с миддлами и админами, не путается в названиях ключевых технологий, радикально сократил число плагинов, удалил сайт с кошкой, работает.

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

    Синьор
    - собеседование
    указывает на ошибку в тестовом задании, предлагает два решения проблемы, над которой команда пыхтела последнюю неделю и альтернативный стек технологий, на который можно перевести проект
    - испытательный срок
    рефакторит проект, делает билд джун-устойчивым, по ходу дела пишет алгоритм для киллер-фичи, запланированной только на следующий квартал и под конец испытательного срока организует воркшоп, на котором представляет свои наработки "в свободное время" по переводу проекта на другой стек технологий, в которых уже реализована большая часть функционала следующего релиза.
    - работа
    пинками помогает команде в переходе на одобренный руководством новый стек, в чем его активно поддерживает джун, окрыленный тем, что теперь его накопившиеся косяки точно никто не заметит, переводит проект на новый стек, увеличивает производительность в два раза, через год переводит еще раз, периодически генерирует идеи новых продуктов, может пропасть на неделю и вернуться с новой фичей, а может уйти в накопившийся за несколько лет отпуск и больше не вернуться, т.к. случайно встретил старого знакомого, передложившего другой мега-проект с гига-зарплатой.
    Ответ написан
    4 комментария
  • Можно ли делать делать выборку секретных данных из бд по guid?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    ...а потом у пользователя угоняют эту куку, и начинается веселуха со всеми отягчающими. Так что, сделать-то, оно, конечно можно, но определенно - не нужно (ибо этот вариант уступает по надежности даже обыкновенной сессии php)!
    Если уж хочется как-то выпендриться на тему секюрити сессии, то, по крайней мере, в каждом ответе выдавать новый токен и потом только по нему идентифициривать сессию. И все это, разумеется, под SSL.

    А, вообще, детство это все... SSL с двухсторонней авторизацией - вот в чем залог счастья :)
    Ответ написан
  • Для чего нужны function, в PHP ?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Функции нужны для того, чтоб в коде не возникали ошибки и хаос. Если весь код состоит всего из нескольких переменных и операций, это понять сложно. Но как только их становятся десятки, сотни и тысячи, без разделения кода на изолированные логические кусочки (функции) уже не обойтись.

    Функции позволяют писать программы, постепенно углубляясь в отдельные аспекты и не теряя при этом "общую картину". Например, в программе нужно получить данные с сервера, распарсить их, что-то посчитать и вывести результаты. Вместо того, чтоб писать простыню, в которой тут же запутаешься, можно разбить код на функции getData() - parseData() - performCalculation() - displayResult(), и постепенно писать их логику, концентрируясь на решении конкретной задачи отдельной функции. Разделение сложной задачи на более простые - это, вообще, основной принцип борьбы со сложностью. Если это делать разумно (т.е. разделять на осмысленные кусочки), то функции, написанные один раз, можно использовать в разных местах программы (повторное использование кода).

    Наконец, они нужны для сокращения возможных ошибок, т.к. позволяют изолировать переменные, объявляемые внутри функций от случайного их изменения в других частях кода (принцип инкапсуляции в ООП). В случае т.н. глобальных переменных (объявленных в областях видимости, доступных в разных, иногда вообще не связанных друг с дугом логически местах) очень велик шанс объявить переменную для чего-то одного, а потом забыть об этом, и в другом месте использовать ее для чего-то другого.

    И еще они позволяют вносить изменения в логику программы, не перекраивая ее для этого целиком (полиморфизм). Если в примере выше вдруг понадобится изменить алгоритм рассчета, достаточно изменить performCalculation() (или даже написать другую функцию performNewSpecialCalculation() и просто изменить вызов).

    На уровне "внутреннего устройства языка" функции также позволяют эффективно управлять памятью, и обеспечивать взаимодействие программ, написанных разными людьми (например, библиотек), но это уже - совсем другая история.
    Ответ написан
    1 комментарий
  • Есть ли возможность отправить письмо из php, чтобы оно было доступно в папке отправленных в ящике?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Копать в сторону IMAP.

    Update:
    Судя по уточняющим вопросам, нужно таки немного разжевать.

    SMTP, как, впрочем, и PHP, тут совершенно сбоку. Функционал "отправленные" реализуется либо мэйлером (локально), либо провайдером. Во втором случае это просто папка на сервере. Как конкретно в нее попадает копия, одному провайдеру известно. В любом случае, по SMTP нельзя получить доступ к папкам - можно просто сбросить письмо, и надеяться, что оно будет доставлено.

    Совсем другое дело IMAP. По IMAP можно получить доступ к папкам и, например, самостоятельно откладывать копию в соотв. папку, после того, как письмо успешно ушло по SMTP.

    SMTP к этой истории имеет лишь то отношение, что он обычно осуществляет (если осуществляет) авторизацию пользователя.
    Ответ написан
    3 комментария
  • Медленный парсинг XML средствами PHP. Как увеличить скорость?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    LIBXML_COMPACT ?
    А, вообще, проблема, похоже, архитектурного плана. Если файлы небольшие, то время, в основном, расходуется на выкачивание по HTTP. Выкачайте 20 файлов, положите на диск и сравните производительность. Если подтвердится, поможет только какое-нибудь умное предварительное кеширование.
    Ответ написан
    2 комментария
  • Как правильно учитывать остаток товара на складе?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    С точки зрения бухгалтерии есть и третий, правильный вариант: остаток = доступный + зарезервированный товар. Положили в корзину = зарезервировали. Оплатили -> ничего не делать. Оплата не прошла = "разрезервировали" и принудительно выкинули из корзины.
    А остаток, как таковой, уменьшать только по факту отгрузки (накладная).
    Ответ написан
    Комментировать
  • Оптимальная структура БД. Как организовать правильно?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Нет такого понятия, как вообще оптимальная структура данных. В данном случае можно, например, создать две доп. таблицы:
    item_name (id, name);
    item_user_price(id_user, id_item, price);

    В первой будет "более 200" записей (которые, кстати, со временем могут удаляться / добавляться), во второй - столько, сколько цен будет вводиться пользователями (сомневаюсь, что пользователи будут рады, вводить все 200 цен за раз; а может у кого-то вообще есть не все цены).

    Такая структура даст минимальную избыточность. Но будет ли она "оптимальной" по скорости и расходу памяти, зависит от конкретных запросов, которые на ней будут выполняться.
    Ответ написан
  • Как написать регулярку ?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Как завещал великий Кот Матроскин: чтобы оттримить что-нибудь ненужное, сначала нужно выбрать что-нибудь ненужное. Таким образом, если не выбирать то, что не нужно, то и тримить ничего не придется. На то они и регулярки...
    preg_match("/\S+/", $input_line, $output_array);
    Я допускаю, что в это трудно поверить, но запрет на изучение и написание регулярных выражений давно отменен! Сегодня регулярки вполне реально не только написать, но и проверить своими собственными руками, например здесь.
    Ответ написан
    Комментировать