• Подбор платежной системы (есть критерии)?

    Mendel
    @Mendel
    PHP-developer
    Не занимайтесь… в общем глупостями.
    Суммы у вас достаточные, чтобы стоило регистрировать ИП.
    Не знаю как у вас в РФ, но у нас налоги для СПД (ИП) значительно ниже чем для физиков, и это существенная часть расходов.
    С такими суммами как у вас, да еще если платежей будет по несколько штук в месяц (иначе зачем сыр-бор?) очень рисково нарушать закон…
    Ответ написан
    2 комментария
  • Где купить lcd матрицу от 10" с подключение по usb или hdmi?

    Mendel
    @Mendel
    PHP-developer
    Что есть «стандартный шлейф»?
    Я бы гуглил что-то более конкретное, типа «lvds usb converter»
    Ответ написан
    1 комментарий
  • Можно ли доверять HTTP_REFERER (предварительно прочитайте вопрос)?

    Mendel
    @Mendel
    PHP-developer
    для XSRF лучше использовать токены.
    Даже если все комбинации юзерского софта будут защищать реферер, то никто не знает какую уязвимость найдут завтра.
    Когда я последний раз этим интересовался (давно) возможность атаки имела место.
    Ответ написан
    5 комментариев
  • set_time_limit не работает, скрипт отрабатывает бесконечно долго

    Mendel
    @Mendel
    PHP-developer
    Отделите мух от котлет.
    Сделайте тест, в котором будет только сет_тайм_лимит и бесконечный цикл, т.е. в две строки.
    Так вы локализуете проблему — это с вашим окружением или с кодом.
    Ответ написан
    Комментировать
  • Вызов хранимой процедуры php PDO, firebird?

    Mendel
    @Mendel
    PHP-developer
    Всё указывает на то, что ошибка здесь:
    $sql="CALL P_NAME_ID (?,?,?,?)";
    

    Я не знаю firebird, так что не подскажу дальше. Но глаз режет отсутствие точки с запятой. По идее она не обязательная но…

    PS: на вскидку гугл мне не выдал ничего про
    зато выдал про
    CALL P_NAME_ID
    

    EXECUTE PROCEDURE
    

    Уверенны в синтаксисе?
    Прямое выполнение инструкции в консоли ошибку не выдает?
    Ответ написан
    3 комментария
  • Регистратор ТМ в Украине (совет)?

    Mendel
    @Mendel
    PHP-developer
    armid, рекомендую обратится к Zegaldis.
    К nic.ua я бы не обращался, у них слава с душком. Если вы рассматриваете ТМ чисто под домен, т.е. это некий ключ, то это вдвойне опасно.

    Что касается ТМ под домен за полтора-два года, то забудьте сразу. Либо вы хотите слишком уж паршивенький домен, и никто на него не позарится, либо пока будет «зреть» ваша ТМ, кто-то другой быстренько сделает ТМ _в_другом_классе_ (специально обращаю внимание ибо некоторые не понимают о чем речь), и возьмет себе домен. А ТМ да, вы потом получите :)
    Ну и если ищете себе патентного поверенного, то берите такого у которого хорошая репутация именно в домейнерских кругах. Ибо либо человек не понимает специфику доменов, и может не подсказать как правильно оформить заявку на ТМ с ключевиком, которую может зарезать экспертиза… либо если он разбирается в доменных нюансах, но не особо известен, то может легко сделать ход как описано выше — кинуть на домен.

    Еще раз на счет ускоренной регистрации — если вы хотите взять ТМ под некое название, которое никому кроме вас не понадобится, то да, вы можете ждать два года (два а не полтора, потому что полтора это _официальные_ сроки, а чиновники любят сильно затягивать, так что адекватный поверенный сроки называет с запасом). Но тогда это не ТМ под домен, а ТМ под проект, который волей случая связан с интернетом. Если же это крутой домен, который может быть интересен другим, то очень большой риск, что вас перехватят. Существуют списки поданных заявок, эти списки бывают как официальными, так и неофициальными, и те кто этим зарабатывает имеют такие списки. Так что будьте уверены — то, что вы хотите себе такой домен, несколько десятков человек узнают. И кто-то с высокой долей вероятности возьмет его себе.

    И еще совет — если берете под реальный проект, то я бы не жадничал, а сделал две ТМ. Одну «боевую», под домен, со всеми нюансами, чтобы было эффективно. Вторую красивую, на два года запулить, в своем классе, со всеми рюшками…
    Ответ написан
    1 комментарий
  • ТЗ на разработку программного обеспечения?

    Mendel
    @Mendel
    PHP-developer
    Я всегда придерживался принципа, что идеальное сферическое ТЗ в вакууме это такой документ, который в будущем станет документацией на продукт.

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

    Инструкцию всегда можно просто и быстро превратить в ТЗ. А если вы не готовы писать инструкцию, то вы не готовы писать ТЗ, т.е. еще не имеете достаточного понимания структуры, задачи и т.п. Может быть она и появится в процессе написания…
    Ответ написан
    Комментировать
  • Кто может объяснить, зачем мне GIT?

    Mendel
    @Mendel
    PHP-developer
    Управление историей. Нетбинс любит терять историю, реально рассчитывать на нее нет смысла. А тут это основа.
    Ветвление и слияние. Когда нужно делать большое изменение, а система уже в продакшене, и ты вынужден ее поддерживать, то сделать ветку, и править на ней, а потом объединить ветки, да так чтобы не затереть изменения в обеих — почти невозможно когда нет системы управления версиями.
    Совместная работа. Пропадает всякий бред типа в аське писать мол не трогай такой-то файл, я его правлю…
    Сотни мелких коммитов с описаниями. Т.е. делаешь изменения, и сразу описываешь, и сразу видно в каких файлах это было и когда… Помогает в расследованиях, в документировании.
    Возможность контролировать «что изменилось». Анекдотичный случай — я как-то в четыре часа ночи решил переименовать в одном классе модели поле desc на _text. Оно фигурировала в нескольких сотнях классов, поэтому я использовал поиск и замену. Полуручную.

    Через месяц у меня выплыл глюк с сортировкой данных. Оказывается при поиске я случайно заменил desc в запросах в ORM. Был бы тогда GIT да получше покрытие тестами — не пришлось бы два часа искать причину. Я бы увидел, что у меня есть изменение в таком-то файле, а оно там неуместно…

    Причин много может быть. Но возможно просто ваши объемы сложности еще не требуют от вас таких решений.
    Ответ написан
    2 комментария
  • Google и сертификат безопасности?

    Mendel
    @Mendel
    PHP-developer
    firefox v21.0

    Работают все трое
    google.ru
    google.com
    google.com.ua
    работают как с https так и http, как с www так и без www (с соответствующей переадресацией)

    Сертификаты подписаны самим гуглом. соответствующий сертификат есть в базе.

    Вместе с тем действительно вижу много сообщений о том что у людей проблемы.
    У меня есть две гипотезы:
    1 — возможно вы не обновляли браузер, а у гугла что-то изменилось с подписанием.
    2 — может быть в Украине отдают контент другие фронт-энд сервера, у которых еще нет проблем.
    Ответ написан
  • Подобрать архитектуру распределённого Yii-приложения?

    Mendel
    @Mendel
    PHP-developer
    Первое что Вам нужно сделать это разобраться с guid.
    Я не пробовал этого в Yii, но насколько я помню навскидку там не должно быть серьезных препятствий к его использованию.
    Если есть какие-то наработки, модули модели и т.п., то надо будет их приучить к новой структуре. Поменять типы полей в базе (включая связанные), поменять автоинкремент на генерацию гуид по вашей логике и т.п.

    Создаете себе базовый класс наследник от CActiveRecord, скажем CDistributedActiveRecord.
    Этот класс у вас будет отвечать как за guid так и за репликацию.
    Собственно все АР наследуют от него.

    Проектирование архитектуры нужно начать с четкого планирования базы.
    Очевидно что часть таблиц у вас будут уместны во всех базах, без фильтрации. К примеру таблица содержащая список организаций в вашей иерархии нет смысла. Вообще стандартная логика обычно такая — «справочники» мы имеем общие, «документы» у каждого свои. К примеру номенклатуру (товары, виды услуг и т.п.) лучше отнести к справочникам, и тиражировать централизованно, а вот к примеру прайс из этой номенклатуры лучше считать документом (но опять де от специфики зависит). «Документы» и «справочники» нам не обязательно делать так строго как в 1С, мы ведь свою архитектуру делаем. К примеру сотрудники/пользователи по логике это справочник, но мы можем отнести его к документу, и вообще сделать два базовых класса для них. Это опять таки сильно зависит от вашей задачи.

    Далее вам необходимо будет создать критерий, по которому вы будете определять кому принадлежит тот или иной документ, и нужно ли его передавать. В простейшем случае это будет идентификатор предприятия/подразделения. Очень хорошо будет, если он будет у вас простой, и универсальный. Т.е. чтобы он во всех таблицах которые реплицируются был одинаков. Пусть он будет у нас называться ПредприятиеВладелец.
    Обратите внимание, что если вышестоящие подразделения будут не только просматривать данные нижестоящих, но и вносить в них изменения, или еще хуже — создавать связанные с ними новые документы, то вы должны указывать этим документам правильное ПредприятиеВладелец. Если документ подразумевает, что его должны прочитать в подчиненном предприятии (к примеру это документ содержащий резолюцию по заявке полученной из подчиненного подразделения), то необходимо указывать у такого документа ПредприятиеВладелец равное тому, которое было указано в документе связанном с этим (т.е. в нашем примере Владелец из «заявки»). Если вы укажете Владельца равного предприятию в котором был создан документ, то потом придется городить сложные критерии того какой документ передавать при репликации и кому передавать.

    Совет — сильно подумайте о внешних ключах. Как это отразится на ваших ручных репликациях.

    Теперь перейдем собственно к репликации. Тут я сделаю несколько допущений. Если они неверны, то озвучьте. Для начала я предположу, что вам не нужна реалтайм репликация. Т.е. было бы хорошо, чтобы все документы появлялись в ту же милисекунду в другой базе, но если будет задержка даже в несколько минут, то никто не умрет, не будет нарушена целостность данных и т.п. Второе допущение — скорее всего у вас будет не много маленьких изменений больших записей. Т.е. если вы не создаете запись, а вносите в нее изменения, то вы все равно можете передать всю измененную запись, а не только изменения, и при этом излишние накладные расходы будут не очень высокими. К примеру если вы даже передаете в базе файлик, который весит несколько мегабайт, то вы либо изменяете сам файл и размер изменения большой, либо его описание, которое занимает небольшую часть общего объема. В идеале если у вас ожидается большое количество изменений этого самого описания, без изменения «файла», то лучше разделить это на две связанные таблицы, чем городить сложную репликацию.

    Если мои ограничения вам подходят, или вы готовы под них подстроится, то можем переходить к репликации.
    Для репликации мы переопределяем методы создания и изменения записей таким образом, чтобы они сохраняли наши изменения в журналы.
    Журналы могут быть как у каждой реплицируемой таблицы, так и общие для всех. Зависит от задачи. Журналы у нас содержат в себе только:
    инкрементарный номер записи, который представляет из себя «скрытое время», который является сквозным для всех таблиц, возможно название таблицы, и guid изменяемой записи. Также мы указываем что произошло с записью. для целей репликации у нас есть два действия — сохранение и удаление. Нам не интересно была ли запись создана, или редактируется старая — все равно нам ее передавать.

    Далее мы создаем еще одну таблицу, в которой у нас будут указаны узлы с которыми у нас предусмотрена связь. Здесь может быть что угодно, включая реквизиты для связи с узлом, но обязательными полями должны быть — признак того, какие именно записи передавать (поскольку некоторые данные могут передаваться в несколько узлов сразу, то нет смысла выносить это в журналы репликации) и два номера обработанных записей: входящий и исходящий (не путать с номерами сообщений в 1с). В этих номерах мы будем отражать какие записи из журналов репликации мы получили или отправили (или если у нас будет оффлайн репликация, то какие изменения мы отправили и получили о них подтверждение о получении). Далее при передаче инфы соседям, мы будем делать запрос в журнал репликации, который будет отбирать только данные с нужным ПредприятиеВладелец (или без ограничения если у нас отправка «наверх») и с номером записи больше чем номер уже обработанный. Имея список записей которые нам надо отдать мы ищем их в соответствующих таблицах, формируем пакет для синхронизации, и отправляем его. При получении пакета мы проверяем записи на факт того, не являются ли эти записи уже отработанными до этого (проверяем по номеру, особенно критично для оффлайн синхронизации).

    Обратите внимание — мы не храним все изменения, а храним только номера измененных записей. При получении мы или изменяем запись, или создаем новую если таковой нет, или удаляем если указано удалить.

    Как передавать информацию? да как угодно. Хоть по почте кидайте в виде json.

    Не забывайте чистить «журналы репликации» от записей которые уже не нужны никаким из узлов с которыми есть связь (т.е. чьи номера меньше чем ВСЕ исходящие номера у всех узлов). Также хочу обратить ваше внимание на размерность счетчика-идентификатора в этом журнале. Делайте его побольше :)

    Что еще важно в большой, распределенной системе? Важны тщательно продуманные права пользователей, и важны ЛОГИ. Много больших и разных логов. Еще больше логов. Логи для разбора полетов лучше всего вести отдельно от журналов репликаций. В них требуется большая детализация чем там, с другой стороны они читаются редко, а пишутся часто, так что индексация нужна в меньшей степени. обязательно указывать кто вносил изменения, когда вносил и т.п. В идеале такие журналы держать вообще в отдельной базе или даже в текстовом файле.

    Вроде пока всё что вспомнил.
    Ответ написан
    2 комментария
  • Собственное мнение. Существует или это миф?

    Mendel
    @Mendel
    PHP-developer
    Есть такое. ИМХО это недочет алгоритма голосования.
    Я писал когда-тов саппорт с предложением сделать вес голоса как кармы так и комметнариев/топиков взвешенным относительно склонности человека минусовать/плюсовать, т.е. минусовщикам делать низкий вес минуса и высокий плюса — альтруистам наоборот.
    Предлагал уменьшить вес «личной неприязни», т.е. уменьшить вес голоса, если человек недавно уже голосовал по комментариям конкретного человака.
    Предлагал вынести кнопку голосований в карму сразу в комментарий, чтобы не нужно было ходить в акк пользователя.

    На всё это мне сказали что система и так сложная, и нечего ее трогать.
    Ответ написан
    4 комментария
  • Один номер телефона на двух мобильных устройствах?

    Mendel
    @Mendel
    PHP-developer
    Еще как вариант можно делать две карты, с переадресацией, а на вспомогательной карте заказать услугу «Приватный номер». Если тариф не сильно бьется по карману, то знакомые не будут видеть с какого номера вы звоните, и не смогут на него перезвонить.
    Ответ написан
  • WEB-программирование. Что выбрать и с чего начать?

    Mendel
    @Mendel
    PHP-developer
    ИМХО в вашем случае стоит начинать с пхп.
    Поскольку вы имеете опыт работы с более-менее строгими языками, то либерализм пхп не должен повредить детскую неокрепшую психику. Правда стоит таки включить E_STRICT сразу когда начнете писать.

    Преимущество пхп для новичка — есть работа для новичка. Слишком много нужно выучить общих технологий, чтобы можно было претендовать даже на юниора в более продвинутых языках.

    Вы только не ведитесь на эту либерастию… сначала упиваешься как круто, что тебя ни в чем не ограничивают, потом свыкаешься с мыслью что многих привычных инструментов нет (и это вам еще повезло, вы не застали ООП в пхп4). Потом жизнь кажется прекрасной… а когда переваливаешь через мегабайт кода, начинаешь ныть «дайте, дайте, дайте мне жесткую типизацию!!! расрас», включаешь E_STRICT и сразу узнаешь о себе много нового…

    Итог: советую пхп, но сразу писать строго. Начните с одного из стандартов оформления кода…
    Ответ написан
    2 комментария
  • PHP Cluster и файлы сессий на общем файловом хранилище. Возникают бесконечные блокировки?

    Mendel
    @Mendel
    PHP-developer
    Не хочется говорить банальные вещи, но ИМХО необходимость блокировки сессий и при этом отказ от привязки ip пользователя к конкретному серверу это признак ошибки в архитектуре.

    Подумайте, возможно стоит часть данных из сессии вынести в базу? Ту самую часть, которая так критична к блокировкам.

    Вообще странно, что при такой нагрузке у вас возникают проблемы. Каково количество сессий в момент блокировки?

    Как вы работаете с сессиями? Стандартный обработчик, или таки что-то свое в session_set_save_handler, но тоже работающее с файлами?

    Есть стойкое ощущение, что сессия по каким-то причинам не освобождается. Может быть поможет register_shutdown_function('session_write_close'); Хотя я так и не понял из документации какой в этом смысл, но зачем-то session_register_shutdown было придумано…

    Еще я бы на вашем месте покурил www.php.net/manual/ru/function.session-write-close.php, а точнее комментарии к ней. ИМХО там описано пару кейсов которые могут оказаться вашими.

    Один раз я встретил очень забавный случай, который приводил к проблемам с сессиями на относительно небольшой нагрузке — в одном проекте сессии инициировались не только там где было уместно, но и даже в статики. Про генерируемые картинки, которым сессии были вообще не нужны я вообще молчу…

    Попробуйте в session_set_save_handler сделать логирование открытий/закрытий, уничтожений вызовов мусорщика и т.п. Может быть это даст вам ключ к пониманию проблемы.

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

    Mendel
    @Mendel
    PHP-developer
    Либо статьи разные, либо одинаковые… Если две статьи одна за одной и одинаковые, то за это стоит минусовать.

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

    Mendel
    @Mendel
    PHP-developer
    ИМХО определение пояса пользователя по IP не очень удачно. Я бы брал текущее время с пользовательского компьютера, и на его основе вычислял пояс. (Погрешность часов можно предположить в пределах получаса, т.е. отклонение количества минут от ожидаемого по реальным часам выбираем с тем знаком, который меньше по модулю).
    В идеале конечно сравнивать два результата — по IP и по браузеру, и если получается разные цифры то спрашивать пользователя.
    Заодно и подсказать пользователю как перенастроить время в его операционке (как переставить часовой пояс как минимум. У нас часто бывает что у людей на компе стоит часовой пояс МСК просто потому что он ставится мастдаем по умолчанию, а люди не знают как менять часовой пояс, меняют время… при следующей синхронизации время сбрасывается, и люди на это забивают).
    Ответ написан
  • Как получить содержательную часть страницы?

    Mendel
    @Mendel
    PHP-developer
    Вот здесь я использовал для этих целей два алгоритма — добавить всё это уже описанныйе варианты отбора чистого текста. Отфильтровать тут было чуть умнее — все i, strong, h1 и т.п. заменял на b.
    Все p, span, div и т.п. заменял на разделитель какой-то (не помню уже). Все незначащие теги типа head img и т.п. удалял.

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

    Если кому будет интересен мой говнокод шестилетней давности (а он 99% что дикий был), то могу дать в личку. Но лучше воспроизведите алгоритм сами. Будет адекватнее :)
    Ответ написан
    Комментировать
  • Как грамотно выводить и определять похожие новости на сайте?

    Mendel
    @Mendel
    PHP-developer
    Теги это хорошо. Но не всегда применимо. Не всегда они есть, и в достаточном количества.
    Название может сильно отличаться, хотя тоже немаловажно.
    Если проект на php то библиотеку скорее лучше брать phpmorphy.
    ну или стеммер какой, но тогда слова в качестве тегов пользователю не выведешь.

    Первое что приходит в голову это примерно такой алгоритм:
    1 — приводим тексты к базовой форме
    2 — отбрасываем все стоп-слова по словарю. Можно еще по морфемам от phpmorphy отбирать, но это ИМХО излишнее. Проще словарь ручками под себя оттюнинговать.
    3 — прогоняем через синонимизацию (опционально, на самом деле от тематики зависит и качества словаря, иногда уж лучше и не гонять).
    4 — вычисляем релевантность наших слов тексту. Я бы взял самый простой алгоритм с тошнотой. Только добавил бы весу словам из заголовка статьи и если есть большое желание добавил бы веса с учетом выданных phpmorphy морфем. (к примеру прилагательным давал бы меньше вес чем существительным)
    5 — отбираем топ-N наших ключевых слов, и привязываем их каждой статье. Колво ключей выберете исходя из Вашей задачи, но по опыту думаю это будет между 5 и 10.
    6 — теперь самое сложное. Нужно сделать запрос. Тут нужно курить и экспериментировать. ИМХО стоит вычислять некий «рейтинг» близости, тут или количество совпавших слов из нашего топа подойдет, или сделать это колво взвешенным (в зависимости от позиции слова в списке или от его веса в тексте). Дальше уже сильно все зависит от реализации, от ORM и т.п.

    ПЫСЫ: на счет морфологической омонимии — лично я в подобных случаях тупо брал первый попавшийся вариант. Суммарно это очень незначительно влияло на результат, а разрешение морфологической омонимии это еще та задача :)
    Ответ написан
    Комментировать
  • stream_socket_server — не работают http_headers

    Mendel
    @Mendel Автор вопроса
    PHP-developer
    Подсказали на другом форуме:
    fwrite($client,  "200 OK HTTP/1.1\r\n" 
    

    Замени на
    fwrite($client,  "HTTP/1.1 200 OK\r\n"  
    

    Забавно оказалось.
    Ответ написан
    Комментировать