Июн 17

Буквально 3 дня назад имел счастье поразбираться (полазить по кодам) — такое случается редко, и после подобных разборок довольно хорошо поднимается экспириенс. А что еще нужно программисту кроме регулярного поднятия уровня опытности!?

Описание диспозиции

Есть форма, в этой форме есть поле для ввода даты/времени, для удобства ввода прикручена к этому полю JavaScript библиотека JSCalendar (симпотичный и удобный выпадающий календарик)

По сабмиту дата/время вставляется в таблицу в виде UnixTime, для конвертации в формат UnixTime использую следующую функцию

function format_to_unixtime($t)
{
   list($date, $time) = split(' ', $t);list($day, $mon, $year) = split("/", $date);
   list($hour, $min) = split(':', $time);    return mktime($hour, $min, 0, $mon, $day, $year);
}

Для работы с базой данных MySQL использую библиотеку Дмитрия Котерова DBSimple.

Проблема

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

Сложилось стойкое впечатление, что на каком-то этапе к дате плюсутся 6 часов из за смещения по гринвичу.

Следующий тестовый пример показал что дело в функции mysql FROM_UNIXTIME

include_once('conf.php');
include_once('lib/dbsimple/mysql.php');
//Подключаемся в MySQL
$db = DbSimple_Generic::connect("mysql://".$mysql_user.":".$mysql_passwd."@".$mysql_host."/".$mysql_db);
// Устанавливаем обработчик ошибок MySQL.
$db->setErrorHandler('databaseErrorHandler');
$db->setIdentPrefix($mysql_table_prefix);

$dt = '18/06/2008 10:10';

$db->query("insert into test (dt) values (?)", format_to_unixtime($dt));

echo $dt."
"; echo format_to_unixtime($dt)."
"; $recs = $db->select("select id, dt, FROM_UNIXTIME(dt, '%d/%m/%Y %H:%i') ddt from test"); print_r($recs); function format_to_unixtime($t) { list($date, $time) = split(' ', $t); list($day, $mon, $year) = split("/", $date); list($hour, $min) = split(':', $time); return mktime($hour, $min, 0, $mon, $day, $year); } ?>

18/06/2008 10:10
1213783800
Array
(
[id] => 1
[dt] => 1213783800
[ddt] => 18/06/2008 16:10
)

А вот что написано на странице http://dev.mysql.com/doc/refman/6.0/en/date-and-time-functions.html

FROM_UNIXTIME() functions return values in the connection’s current time zone, which is available as the value of the time_zone system variable.

Вывод: читать документацию надо чаще.

автор: \\ теги: , ,

Апр 15

Значит ситуация такая, есть у меня на работе замечательная программы 1С-архив. Использует она в качестве СУБД MSSQL. Собственно я это все хозяйство не сопровождаю, но есть на нашем внутреннем сайте отчеты по исполнению заданий, данные этих отчетов берутся из MSSQL.

Отчеты имеют параметрами:
Автора задания;
Исполнителя;
две даты;
Исполнение: Просрочено/Вовремя/Все;
Состояние: В работе/Выполнено/Все.

Все прекрасно работало!

Звонит значит мне админ 1С-архива, через много месяцев работы отчетов и просит зайти к нему.

А дело оказалось в том, что при обращении к хранимой процедуре с опр. параметрами выдавалось 3 записи в браузере (PHP, Apache, Solaris). А с теми же параметрами в программе MS SQL Server Management Studio (Windows XP)выдавалось четыре записи.

Реальный такой полтергейст.

Для чистоты эксперимента распечатал переменную SQL в браузере, в MS SQL Server Management Studio также 4 записи, а в браузере 3.

Ппц.

Посмотрели логи сервера, запросы попадающие серваку идентичны. Много было высказано в адрес Microsoft…

Решение

Причина была в том, что сравнение дат давало сбой. В SQL даты передавались строково и преобразовывались CONVERT(SMALLDATETIME, @FromDate) где @FromDate — строка

А нужно было

CONVERT(SMALLDATETIME, @FromDate, 104)

Применение данной функции было в нескольких местах, и только в одном месте допущена опечатка.

Зы. Процедуру писал не йааа 🙂

автор: \\ теги: , ,

Мар 13

Ниже приведенный php код не печатал адекватно русские буквы

$im = imagecreate(140, 50);
imagecolorallocate($im, 255, 255, 255);
$text_color = imagecolorallocate($im, 0, 0, 0);
$txt = "Привет";
imagettftext($im, 12, 0, 45, 15, $text_color,'verdanab.ttf', $txt);
imagepng($im);

Пробовал заставить работать по разному, скармливал например в UTF, windows-1251, KOI8-r кодировках, ничего не помогло.

Вспомнил, что на сайте работает библиотека jpgraph, которая выводит всякую графику для анализа в виде а-ля Excel. Данная библиотека также как и вышеприведенный код, генерирует графику через GD. Там на графиках русский был читабельный.
Начал раскопки …

function iso2uni ($isoline)
{
   $isoline = convert_cyr_string($isoline, "w", "k");
   $isoline = convert_cyr_string($isoline, "k", "i");
   for ($i=0; $i < strlen($isoline); $i++)
   {
      $thischar=substr($isoline,$i,1);
      $charcode=ord($thischar);
      $uniline.=($charcode>175) ? "&#".(1040+($charcode-176)). ";" : $thischar;
   }
   return $uniline;
}

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

ЗЫ. Я так понимаю, что у многих людей таких проблем не возникает, т.к. в интернете по форумам подобного решения не видел, обычно у людей проблема в том, что библиотеки не установлены.

автор: \\ теги: , ,

Янв 20

Дело было так:

Звонит пользователь и жалуется что сортировка вывода данных из MySQL неправильная, т.е. не по алфавиту.

Полез в php скрипты и вытащил запрос который так криво работал,  примечательно что в order by стояло поле по которому нужно было сортировать по алфавиту, вобщем вытащил sql запрос и запустил его в утилите SQLyog. Запрос выдал данные но сортировка по указанному в order by  полю не была адекватной.

Полез в свойства таблицы все тем же SQLyog, командой alter_table, смотрю, а на Collation установлено latin1_swedish_ci — вот почему не по русски сортировка! Меняю ее на cp1251_general_ci, жму кнопочку Alter_Table, радуюсь что быстро отделался. Но …

Не тут то было данные в поле испортились, каждая русская буква превратилась в знак вопроса, замена свойства Collation положения не исправило.

#$%^&*

Итого, т.к. данных для восстановления не было пришлось восстанавливать данные руками — 2 дня 3 человека, хотя нет вру не 3 человека, остальные 4 человека работали от 3 часа — 8 часов.

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

ЗЫ. чето дневник у меня получается о глюках MySQL

автор: \\ теги: ,

Дек 08

Проблема:

Есть два веб. ресурса: Один под Solaris_10, PHP_4, MySQL5. А второй WindowsXP, PHP5, MySQL4. Понадобилось мне из Windows обратиться в базу MySQL5 (которая на Solaris). Создал пользователя, чтобы обращаться с любого хоста, а не только в localhost, написал небольшой запрос и о чудо — все русские буквы распечатались знаками вопросов. $%^&* на соляре то все работает и уже давно (

Перерыл весь интернет в поисках рецепта, а там советуют делать правки в my.cnf прописать кодировку или в php скрипте сразу после конекта тоже обозначить кодировку cp1251. Ничего мне из этих советов не помогло.

А помогло вот что. На виндовс запустил из far-a стандартного консольного клиента mysql, но приконектился к серверу который на солярисе, сделал запрос, и что вижу … конечно кракозябры, но не вопросики, т.е. все в порядке!!! буквы windows-1251 кодировки в консоли выглядят кракозябрами. Пишу команду SET NAMES ‘cp1251’ как было написано на многочисленных сайтах найденных гуглом, делаю опять запрос, оппа, теперь вопросики заместо русских букв.

Решение:

Короче говоря в начале работы с mysql в скрипте php поставить след. строку

mysql_query(‘SET NAMES «latin1″‘);

после этого все заработало, осталось только недоумение, почему latin1 правильно отображает русские буквы.

P.S. Вообще в mysql если посмотреть variables много переменных в которых храниться кодировка, конечно каждая переменная отвечает за что то свое, но видимо их многочисленность влияет на путаницу в этом вопросе.

автор: \\ теги: , ,

Окт 23

Ошибка наверное все таки не php, а моя собственная, хотя кто его знает может так и должно обрабатываться …

Итак как я наступил на эти грабли: в массиве $_REQUEST лежит переменная operator в переменной значение 0, в операторе if сравниваю значение этой переменной с нулем

if ($_REQUEST["operator"] != 0)
   echo "Not ok";
else
   echo "Ok";

И вижу на выводе «Not ok». Я точно знаю что в переменной $_REQUEST[«operator»] лежит ноль, более того я вижу это распечатав массив $_REQUEST, командой print_r($_REQUEST);

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

Пока товарищь шел, за эти 5 секунд я поставил ноль в кавычки, и оппа все заработало, и товарищь выпалил что нужно поставить !== (восклицательный знак и два равно), хм всю жизнь сравнивал == или !=, полез в документацию разбираться с темой.

В документации написано:
$a !== $b Неидентичность True, если $а не равно $b, или они разного типа

Товариш был не прав, но его указание из этой темы.

Копаем дальше, функцией gettype($_REQUEST[«operator»]) выясняю что у меня из формы нуль приходит строкового типа, а нуль без кавычек естественно числовой тип. Хм. ну и что PHP слабо типизированный язык программирования, когда нужно приведение типов должно сработать автоматом, но у меня в скрипте в IF этого не произошло 🙁

Итого: Или это у меня такая версия php, или учить php лучше надо было, блин и такие грабли после 3,5 лет программирования на php, стыд и позор.

автор: \\ теги: , ,

Окт 17

 

Собственно ошибку обнаружил выполняя один проект.

Суть: При запросе из таблицы взято значение из поля float (это была цена), нужно было запросить из этой же таблицы все записи с такой же ценой.

Проблема: Ни одной записи по запросу MySQL не вернул. Что довольно таки странно т.к. должна быть хотя бы одна запись из которой эту цифру взяли.

Решение:
По запросу mysql float problem Гугл выдал первой в списке
http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
Где написано о данной проблеме, шо дескать зависит от архитектуры компьютера, т.е. процессор виноват

Потом указано как победить данный казус, т.е. применяя функцию round
и …
перед этим написано
Warning
Never use this method in your applications. It is not an example of a trustworthy method!

и как быть после таких заявлений.

Я конечно в запросе функцию применил, все заработало, но …
… осадок то остался.

автор: \\ теги: , ,