• Как на php выполнить сразу несколько SQL запросов?

    nowm
    @nowm
    Первый способ: сохранить запросы в файл и импортировать этот файл через командную строку. mysql -u user database < /home/username/mysqldump.sql

    Второй способ: можно сократить количество запросов немного поменяв логику построения запроса. Вместо

    UPDATE `products` SET `status` = 1 WHERE `product_id` = 1;
    UPDATE `products` SET `status` = 1 WHERE `product_id` = 2;
    -- 
    UPDATE `products` SET `status` = 1 WHERE `product_id` = 1000;


    можно писать так:

    UPDATE `products` SET `status` = 1 WHERE `product_id` IN (1, 2, 3, 4, 5);
    UPDATE `products` SET `status` = 2 WHERE `product_id` IN (6, 7, 8, 9);


    Update: оу... я так медленно пишу. Когда начинал писать, ни одного ответа ещё не было. ))
    Ответ написан
    Комментировать
  • Как в SQL выбрать пользователей, у которых день рождения в ближайшую неделю?

    nowm
    @nowm
    Можно добавить в SQL-запрос условие:

    WHERE TIMESTAMPDIFF(DAY, `birthday`, NOW()) BETWEEN 0 AND 7

    WHERE TIMESTAMPDIFF(
        DAY, 
        DATE_ADD(`birthday`, INTERVAL YEAR(NOW())-YEAR(`birthday`) YEAR), 
        NOW()
    ) BETWEEN 0 AND 7

    (На несколько строк разбил только для того, чтобы было удобнее читать.)

    Спасибо @Kerman за подсказку — совсем не подумал про то, что нужно обратить внимание на год в `birthday`.
    Ответ написан
    Комментировать
  • Как сделать кнопку наверх без прокрутки?

    nowm
    @nowm
    По-моему вот такая конструкция будет нормально везде работать:

    <a onclick="$(document).scrollTop(0);">Наверх</a>

    На тач-устройстве, во всяком случае нормально работает — не только на компьютере с мышью. Никакой анимации. Реализовано с помощью jQuery, так как у вас в тегах это упоминается.

    Или, если нужна именно кнопка:

    <button type="button" onclick="$(document).scrollTop(0);">Наверх</button>


    И вообще можно практически любой элемент так использовать.

    При использовании тега < A > с атрибутом href, нужно добавить в onclick инструкцию return false, чтобы переход по ссылке не происходил:

    <a href="#" onclick="$(document).scrollTop(0);return false;">Наверх</a>


    Если href не используется, то return false не обязательно указывать.
    Ответ написан
  • Почему при настройке Sublime Text на активной вкладке выделяется текст в прямоугольные формы и на полях помечается восклицательным знаком?

    nowm
    @nowm
    Поставьте курсор на строку 8 и посмотрите на статусную строку (где сейчас написано «Line 5, Column 1»). Там будет написано, в чём дело. У вас наверное установлен Sublime Linter — это он так выделяет ошибки.
    Ответ написан
    Комментировать
  • Русский шрифт roboto slab или альтернатива?

    nowm
    @nowm
    Он вполне себе поддерживает кириллицу. Вот для примера: www.fontsquirrel.com/fonts/roboto-slab

    Откройте вкладку «Test Drive» и введите русский текст, он нормально его отображает.

    С Google Fonts опять же можно скачать: www.google.com/fonts#UsePlace:use/Collection:Robot...

    Просто поставьте галочку на «Cyrillic» в разделе «2. Choose the character sets you want:»
    Ответ написан
    Комментировать
  • Путь из фрилансера в аутсорс контору. Как?

    nowm
    @nowm
    Когда начинают закидывать работой, лучший способ — повышать цену.

    Кстати, у многих заказчиков на одеске совершенно нормальная практика: платить 5-10 долларов программистам из Индии, 15-25 долларов — программистам из России и 50-60 долларов — программистам из США. Даже если сложность работы совершенно одинаковая в каждом случае.

    Вот тот владелец студии, которого вам удалось допросить, просто притворился американским программистом. И совершенно логично и нормально, что ему платят в несколько раз больше, чем другим, ведь все думают, что он из США, ведь у него там офис и реклама. А он в России платит намного меньшие ставки местным работникам. При этом, для этих работников ставки выглядят вполне прилично по местным меркам. А себе просто забирает всё, что осталось после расходов.

    Я пишу как обычный мелкий фрилансер — меня пока что не заваливают там работой. Но я просто читаю и анализирую очень много предложений. Именно отсюда моё мнение, что дела обстоят именно так. Кстати, очень часто видел — прямым текстом пишут, что будут платить максимум 20 долларов, но «если вы из США, то вот вам ссылка на вакансию для тех, кто из США». Открываешь ссылку, а там цены ровно в два раза выше при тех же требованиях.

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

    Лучше всего копить деньги, а потом их крутить — вложить в стартап; отдать в брокерскую контору (не самому играть, а отдать им и пусть с ними крутятся и платят тебе обещанные 100% в год); положить в банк под проценты; создать контентный сайт, нанять туда копирайтера средней руки, вложиться в раскрутку и повесить туда рекламу, которая в итоге всё будет окупать и т.д. — в общем, все те вещи, в которых тебе нужно принимать минимальное участие. Это всё рисково, конечно, но если вкладывать их в несколько разных мест, то больше шансов, что они будут приносить доход, а не просто сгорать.
    Ответ написан
  • Как собрать команду энтузиастов-разработчиков для реализации проекта?

    nowm
    @nowm
    Древняя как мир проблема на самом деле в том, что вы хотите (А) грамотных и (Б) надёжных специалистов (которые при этом (В) не сопрут у вас идею), но не хотите им ничего платить.

    У таких проектов итог одинаковый: безденежный генератор идей, когда сталкивается с реалиями красного океана (а вы именно по стратегии красного океана пытаетесь играть, ведь социальные сети — это давно сформировавшийся рынок), просто спрыгивает, оставляя ни с чем тех, кто в поте лица трудился над проектом днями и ночами. Вы ни чем не рискуете — ведь вы не тратите ни копейки на этих специалистов. У вас есть какой-то основной доход, и вы тратите минимум времени на то, чтобы всё направлять. А у этих специалистов, пока они реализовывают ваши идеи, никаких доходов нет. И они рискуют оказаться без денег за свою работу.

    Вы просто наверное не думаете, что этим программистам, дизайнерам и верстальщикам нужно есть, кормить семью, платить за коммунальные услуги и интернет.
    Ответ написан
    2 комментария
  • Что делать, если в Elance Time Tracker отчитался одному клиенту вместо другого?

    nowm
    @nowm
    Не знаю, почему у вопроса тег «oDesk», хотя вопрос по elance. Несмотря на то, что они принадлежат теперь одной компании, это всё равно две разные биржи.

    На одеске, например, перенести нельзя. Можно из таймшита сохранить скриншоты, удалить этот час, показать скриншоты правильному клиенту и договориться насчёт ручного добавления одного часа — тут уже человеческий фактор — как договоритесь. Автоматом перепривязать к другому клиенту не получится. Я видел где-то на форуме одеска предложение добавить такую фишку, но из почти миллиона фрилансеров его отметили только ещё два человека. Сами работники oDesk никак вообще не комментировали этот момент (я имею ввиду предложение, а не саму ситуацию, которая описана в справке).
    Ответ написан
  • Какие есть перспективы у database или security админов?

    nowm
    @nowm
    А вы что, думаете, что индусы проектированием БД не занимаются? Типа, если вы не будете программировать, то у вас будет иммунитет от индусов? Я недавно, например, сталкивался с ситуацией, когда чувак, подразумевая работу с UTF-8, без всякой задней мысли использовал в БД кодировку «latin1_swedish_ci».

    Фиксы индусского кода — это всецело вопрос желания. Я не хочу, например, править 30 файлов, чтобы логотип поменялся на _всех_ страницах сайта (потому что в проекте используется наследование из ущербно-ориентированного программирования), и поэтому не берусь за такие работы. Но это мне не мешает «изучать всякие паттерны и парадигмы ООП», потому что мне нравится программирование. И я в первую очередь им занимаюсь из-за фана.

    А из вашего вопроса видно, что у вас нет фана ни от программирования, ни от БД. И вы в любом случае скатитесь в итоге к тому, что будете искать везде «индусов», на которых можно свалить раздражение из-за того, что вы на самом деле занимаетесь не тем, что вам нравится.

    Перспективы есть и у программистов, и у администраторов БД, и у специалистов по безопасности. Особенно, если им нравится своя работа и они постоянно развиваются, и не боятся, что в будущем встретятся с мифическим индусским подходом.

    (Все моменты, которые я упоминал — реально работа с наследием программистов из Индии. «Индусский» — это было буквальное название, а не собирательное.)
    Ответ написан
    Комментировать
  • Как настроить приложение под структуру бд?

    nowm
    @nowm
    Через /config/main.php это не очень удобно — потому что тогда вам нужно будет предусмотреть ситуацию, чтобы всё это дело записывалось в конфиг, когда администратор сервера захочет что-то модифицировать «через интерфейс».

    Проще создать пару таблиц в БД, которые будут хранить эти поля.

    CREATE TABLE IF NOT EXISTS `table_table` (
      `table_id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(32) NOT NULL,
      PRIMARY KEY (`table_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
    
    INSERT INTO `table` (`table_id`, `name`) VALUES
    (1, 'accounts');
    
    CREATE TABLE IF NOT EXISTS `table_field` (
      `table_field_id` int(11) NOT NULL AUTO_INCREMENT,
      `table_id` int(11) NOT NULL,
      `name` varchar(32) NOT NULL,
      `alias` varchar(32) NOT NULL,
      `label` varchar(64) NOT NULL,
      PRIMARY KEY (`table_field_id`),
      KEY `table_id` (`table_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
    
    ALTER TABLE `table_field`
      ADD CONSTRAINT `table_field_ibfk_1` FOREIGN KEY (`table_id`) 
      REFERENCES `table_table` (`table_id`) ON DELETE CASCADE ON UPDATE CASCADE;
    
    INSERT INTO `table_field` (`table_field_id`, `table_id`, `name`, `alias`, `label`) VALUES
    (1, 1, 'id', 'id', 'ID'),
    (2, 1, 'username', 'username', 'Ваше имя'),
    (3, 1, 'password', 'pass', 'Пароль');


    Потом создаёте модели для этих двух таблиц, контроллеры, реализуете CRUD, и у вас есть интерфейс для настройки полей. «C» и «D» я зачеркнул, чтобы показать, что нужно только оставить возможность читать и редактировать существующие записи, а добавлять/удалять их возможности быть не должно. На странице редактирования, например, нужно сделать так, чтобы доступны для изменения были только «alias» и «label».

    Данные о полях потом получаете как обычно данные из модели получаете. Я бы не стал использовать их как $model->{тут_генерируется_название_поля}, но прямо так навскидку я ничего другого предложить не могу, потому что не вижу всей картины.

    Получать данные из конфига тоже можно, но вы в этот момент потеряете возможность настраивать состав полей через интерфейс (без дополнительных сложностей с чтением/перезаписью PHP-файла из PHP-файла).
    Ответ написан
    Комментировать
  • Как правильно пишется front-end или frontend?

    nowm
    @nowm
    Вот ещё немного рассуждений на эту тему со специализированного ресурса: english.stackexchange.com/questions/34447/is-it-fr...
    Ответ написан
    Комментировать
  • Как можно оптимизировать мой код php+mysql?

    nowm
    @nowm
    Можно не только сократить количество запросов, но и сделать код немного аккуратнее и безопаснее.

    <?php
    // Эта строчка — где-то в другом файле — где в данный момент инициализируется соединение с БД
    $db = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'username', 'password');
    
    $sth = $db->prepare("
        SELECT 
            t.`id`, 
            DATE_FORMAT(rt.`data`, '%d.%m.%Y') remont_date,
            ma.`name` marka,
            mo.`name` model,
            t.`serial`,
            rt.`work_id`,
            rt.`sum`
        FROM `tech` t 
        LEFT JOIN `remont_tech` rt ON rt.`tech_id` = t.`id` AND rt.`status` <> 'delete'
        LEFT JOIN `marka` ma ON ma.`marka` = t.`marka`
        LEFT JOIN `model` mo ON mo.`id` = t.`model`
        WHERE 
            t.`user` = ? AND
            TIMESTAMPDIFF(DAY, rt.`data`, NOW()) BETWEEN 0 AND 30
        ORDER BY rt.`data` DESC
    ");
    $sth->execute(array($myrow['id']));
    $result = $sth->fetchAll();
    ?>
    <table>
        <tr>
            <th>№</th>
            <th>Дата</th>
            <th>Оборудование</th>
            <th>Проделанная работа</th>
            <th>Сумма</th>
        </tr>
        <?php if (!count($result)) : ?> 
            <tr>
                <td>0</td>
                <td colspan="4">Ничего не найдено.</td>
            </tr>
        <?php else : ?> 
            <?php $summ = 0; ?>
            <?php foreach ($result as $key => $row) : ?> 
                <tr>
                    <td><?= $key+1 ?></td>
                    <td><?= $row['remont_date'] ?></td>
                    <td><?= sprintf('%s %s(%s)', $row['marka'], $row['model'], $row['serial']) ?></td>
                    <td><?= $row['work_id'] ?></td>
                    <td><?= number_format($row['sum'], 0, ',', ' ') ?> руб.</td>
                </tr>
                <?php $summ += $row['sum']; ?>
            <?php endforeach; ?> 
            <tr>
                <td colspan="3"></td>
                <td><b>ИТОГО:</b></td>
                <td><b><?= number_format($summ, 0, ',', ' ') ?> руб.</b></td>
            </tr>
        <?php endif; ?> 
    </table>


    А всякие: рамки таблицы, ширины ячеек и прочее — лучше в файле со стилями прописывать, а не инлайном. Их там гораздо проще обслуживать.
    Ответ написан
    Комментировать
  • Как правильно составить регулярное выражение?

    nowm
    @nowm
    Вообще, «(.+)(?P< volume>\d+)?(\s?шт)?$» чтобы выдернуть число — это перебор. Зачем такое сложное выражение?

    m = re.search('(\d+)[\s]?шт', 'Коробка шт с кирпичами 10 шт;')
    m.group(1)


    (Это моя первая в жизни программа на Python, но я её честно протестил перед тем, как публиковать.)

    Edit: более конкретизированная регулярка, которая не реагирует на слова, вроде: «штукатурка», «штанга» и прочие, начинающиеся со «шт»: (\d+)[\s]?шт([^а-яА-я]|$)
    Ответ написан
    5 комментариев
  • Как растянуть li по высоте?

    nowm
    @nowm
    Этот вопрос лучше архитектурно решать. Если вы вместо списка будете использовать таблицу для представления таких данных, то у вас автоматически решится куча вопросов с дизайном. И не нужно будет задавать кучу absolute/relative правил, и текст не будет на метки наезжать, и всё растягиваться будет нормально. Да и вообще, не нужно будет имитировать табличное представление — оно и так будет табличным.

    И для тех же тегов «TD» вполне нормально можно «itemptop» прописывать.
    Ответ написан
    Комментировать
  • Как достать значение селектора?

    nowm
    @nowm
    $(function(){
      $("#occupancy_39311").change(function (){
         if ($(this).val() == "1"){
             $("#price_39315").addClass("p159");
         } else {
             $("#price_39315").removeClass("p159");
         }
      });
    })


    Суть в том, что «#coccupancy_39311 option:selected» — это неправильный подход (могу ошибаться, но буду настаивать). Значение нужно брать из «select». К дочернему «option:select» можно обращаться в том случае, если нужно получить текст этого пункта. Для простоты можно вообще использовать «this», так как внутри change «this» указывает на элемент, к которому применяется.

    С другой стороны, возможно у вас опечатка: «#_c_occupancy_39311 option:selected»

    Ну и название класса должно начинаться с буквы. «159» — не подойдёт.
    Ответ написан
    1 комментарий
  • Как написать такой SQL-запрос?

    nowm
    @nowm
    Вот, примерно так:

    BnSl9aG.jpg

    Всегда пожалуйста! Если ответ вам помог, пожалуйста, рассмотрите возможность выбрать его в качестве решения.
    Ответ написан
    Комментировать
  • Разбор работы dns и подключение поддомена на другой ip

    nowm
    @nowm
    А) Вы можете добавлять какие угодно записи в панели управления доменом (там, где вы его купили). Просто при добавлении A-записи нужно указывать IP-адрес. Если у вас есть выделенный IP на хостинге, то можно даже и не переносить ничего на NS-сервера хостинга — вы этот выделенный айпишник можете присобачивать к домену и слева и сбоку и как заблагорассудится. Обычно NS-сервера хостинга нужно прописывать в том случае, когда хостер не даёт вам выделенный IP-адрес. В этом случае на их NS информация об айпишнике будет оперативно меняться, и если вы привязали их NS-сервера к домену, всё будет обновляться в автоматическом режиме.

    DNS сопоставляет интернет адреса и IP-адреса. Дальше, браузер, когда узнал у DNS на каком айпишнике находится example.com, стучится на этот IP и говорит: «дай мне файл index.php с сайта example.com». Веб-сервер смотрит и видит, что у него в настройках есть example.com, вытаскивает и интерпретирует файл index.php из соответствующей папки. В ситуации, когда в DNS для сайта images.example.com прописан IP гугла, браузер стучится на IP гугла и просит дать ему какой-нибудь файл с сайта images.example.com, а гугл ему отвечает: «иди нах, у меня в настройках не прописано обслуживать запросы для сайта images.example.com. Ты можешь что угодно у себя в DNS писать, но у меня есть настройки web-сервера и там про images.example.com ничего нет».

    Б) pdd.yandex.ru — только для почты

    В) Да, примерно так. Покупает домен и в панели управления доменом (у godaddy) прописывает NS-записи @.example.com указывая в них NS-сервера Hetzner. Потом у Hetzner можно будет в панели управления добавлять поддомены.
    Ответ написан
    1 комментарий
  • Доступ к изображению только для конкретных сайтов (белый список)

    nowm
    @nowm
    Если у вас Apache в качестве веб-сервера, можно не нагружать PHP выяснением того, кто откуда пытается загрузить картинку. Ведь в случае PHP вам все-все картинки придётся отдавать PHP-скриптом — это какая-то лишняя нагрузка.

    С помощью .htaccess можно сделать примерно такой вариант (файл .htaccess в корне сайта files.domain.com):

    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{HTTP_REFERER} !domain\.com$ [NC]
    RewriteRule .* - [R=404,L]


    Я могу ошибаться немного в регулярных выражениях, но суть, я думаю, понятна: проверяем, чтобы строка %{HTTP_REFERER} заканчивалась на «domain.com» (сюда попадут и «domain.com» и «www.domain.com» и «image.domain.com» и «любойподдомен.domain.com»). Если реферер не подходит под это определение, редиректим на страницу 404.

    %{HTTP_REFERER} — это содержимое HTTP-заголовка Referer.

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

    nowm
    @nowm
    Если вы уже до этого получали все данные пользователя из БД, то лучше просто возвращать эти данные из свойств UserController. Да, метод отдельный не помешает, но не обязательно генерировать запрос к БД.

    Например, если вы уже подгружали пользовательские данные раньше и сохраняли их куда-нибудь вроде $this->_model:

    class UserController extends Controller {
      var $_model;
    
      public function loadModel($id) {
        $this->_model = User::model()->findByPk($id);
    
       // ...
    
        return $this->_model;
      }
    
      // ...
    
      public function getBirthday($id) {
        if (isset($this->_model->date) && $this->_model->user_id == $id) {
          return $this->_model->date;
        } else {
          $criteria = new CDbCriteria;
          $criteria->select = 'date';
          $data = User::model()->findById($id,$criteria);
          return $data !== null $data->date : null;
        }
      }
    
      // ...
    
    }


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

    Ваш подход, в принципе, не особенно сильно повлияет на работу сайта — подумаешь, один лишний запрос к БД. Но, вообще, такой подход — неправильный. Тут один лишний запрос, там один лишний запрос. Они в итоге собираются в кучу лишнего потребления ресурсов.
    Ответ написан
    2 комментария
  • Как реализовать JOIN для таблиц в двух БД?

    nowm
    @nowm
    но, по моему, это будет слишком тяжело для баз

    Чтобы для баз было легче, просто сделайте индексы на тех полях, по которым происходит объединение. Один джоин это ещё не «слишком тяжело». Но если вы думаете, что, после запроса с одним джоином, SQL-сервер выйдет из строя на полгода раньше, надорвётся и начнёт глючить, или во время этого запроса будет потреблять электроэнергию, как 100 сварочных аппаратов, то, конечно, можно сделать два запроса, на которые потратится время, а потом потратить время ещё и на цикл в PHP.

    Вообще, лучший способ: замерьте время, которое вам понадобится на то, чтобы получить данные запросом с джоинами, а так же время, которое понадобится для того, чтобы получить данные двумя запросами и с помощью циклов в PHP их объединить. Для чистоты эксперимента, можно вычислять среднее время на 1000 или больше повторений.

    Если у вас базы данных находятся на разных серверах, как вы написали, то самый простой способ — выбрать из каждой таблицы данные отдельно, и уже в PHP сделать объединение. Либо можно использовать FEDERATED таблицы.
    Ответ написан
    Комментировать