Переменная рег. выражения как аргумент ф-ции.
Всем доброго времени суток. Прошу помощи с кодом.
Вообщем, есть такой код:
$a = '2013-04-22 11:22:00';
$month = array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
$a = preg_replace('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2}))/', '$3 '.$month[floatval($2)].' $1г. в $4', $a);
Нужно как-то получить значение из массива $month, но вот воспринимать переменную $2 не хочет, пишет ошибку. Как быть? В итоге должна получится строка: "22 Апреля 2013г. в 11:22". Буду благодарен за помощь. |
Надо обернуть в кавычки:
$month[floatval('$2')]
|
vostok, не работает, в ф-цию так и отправляет строку '$2', в двойные кавычки тоже пробовал - не работает.
|
function dates($a)
{
$month = array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
$reg = '/^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2}):(\d{2})/';
$b = preg_replace($reg, '$2', $a);
return preg_replace($reg, '$3 '.$month[floatval($b)-1].' $1г. в $4:$5', $a);
}
echo dates('2013-04-23 16:47:00');
Сделал так, но мне все равно кажется, что можно сделать как-то проще. |
Так будет работать.
$a = '2013-04-22 11:22:00';
$a = preg_replace_callback('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2}))/', function($matches) {
$month = array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
return $matches[3].' '.$month[floatval($matches[2])].' '.$matches[1].' г. в '.$matches[4];
}, $a);
echo $a;
|
vostok, не работает, ошибка:
Цитата:
$a = '2013-04-22 11:22:00';
$month = array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
$a = preg_replace_callback('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2}))/', create_function(
'$matches',
'return $matches[3].\' \'.$month[floatval($matches[2])].\' \'.$matches[1].\' г. в \'.$matches[4];'
), $a);
echo $a;
|
Цитата:
Ну так ещё можно попробовать:
$a = '2013-11-22 11:22:00';
function callback($matches) {
$month = array(
'Января', 'Февраля', 'Марта',
'Апреля', 'Мая', 'Июня', 'Июля',
'Августа', 'Сентября', 'Октября',
'Ноября', 'Декабря'
);
return $matches[3].' '.$month[floatval($matches[2]) - 1].' '.$matches[1].' г. в '.$matches[4];
}
$a = preg_replace_callback('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2}))/', 'callback', $a);
echo $a;
Если не работает, то наверно надо php обновить или отказаться от этой логики и использовать строковые функции substr() например. |
И если использовать create_function то массив $month надо запихнуть в нее же тогда он будет виден:
$a = '2013-04-22 11:22:00';
$a = preg_replace_callback('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2}))/', create_function(
'$matches',
'$month = array(
"Января", "Февраля", "Марта",
"Апреля", "Мая", "Июня", "Июля",
"Августа", "Сентября", "Октября",
"Ноября", "Декабря"
);
return $matches[3]." ".$month[floatval($matches[2])]." ".$matches[1]." г. в ".$matches[4];'
), $a);
echo $a;
|
vostok, хм... вариант с create_function помог, спасибо.
Вот готовый вариант:
function dates($a)
{
return preg_replace_callback('/^(\d{4})-(\d{2})-(\d{2})\s((\d{2}):(\d{2})):(\d{2})$/', create_function(
'$b',
'$c = array(\'Января\', \'Февраля\', \'Марта\', \'Апреля\', \'Мая\', \'Июня\', \'Июля\', \'Августа\', \'Сентября\', \'Октября\', \'Ноября\', \'Декабря\');
return ($b[1].$b[2].$b[3]==date(\'Ymd\')?\'Сегодня\':$b[3].\' \'.$c[floatval($b[2]-1)].\' \'.$b[1].\' г.\').\' в \'.$b[4];'
), $a);
}
echo dates('2013-04-23 11:22:00');
Может тут ещё что-нибудь можно сжать или что-нибудь сделать, чтобы работало быстрее? |
Цитата:
create_function есть смысл использовать при создании функций на основании информации, полученной во время выполнения программы. Форматируйте код понятнее, понятный код работает быстрее - зачем \' когда можно ". |
vostok, ну в одинарных кавычках код вроде быстрее работает.
|
В вашем случае нет. В коде нет переменных внутри "".
Речь не идет об апострофах обрамляющиx параметры create_function В любом случае это копейки, можете и оставить. У меня вообще сомнения как этот код работает, так как он выглядит вообще не валидно для php (нет возможности потестить), но если у вас работает - значит create_function его понимает. Для скорости нужно оптимизировать алгоритм а не исходники имхо конечно. |
vostok, просто я собираю соц. сеть, и делаю там фотоальбомы: http://mkheroes.p.ht/user/?name=Ruslan_xDD&photo=1
При открытии фотоальбома в javascript приходит массив со всеми датами всех фотографий. В php сначала из mySQL получаем все даты, а потом с помощью цикла создаём массив с датами, массив для JS. Ну и получается, что в цикле каждый раз идёт обращение к ф-ции dates. Вот я и думаю, быстро оно работает или нет, ведь фотографий то может быть и 100, тогда эта ф-ция будет вызвана 100 раз. Так что, я не знаю как сделать лучше, а точнее, чтобы работало быстрее. Может дату разбивать на массив с помощью split()? |
1. На странице можно отдавать не сразу все фото а частями, допустим по 15 (LIMIT 0, 15) на страницу и сделать нумерацию страниц (pagination). Уже функция вызовется не 100 раз.
2. Обратите внимание на функцию array_walk() . Уже не придется писать цикл. Откажитесь от регулярных выражений. Посмотрите в сторону строковых функций. Выбирайте. Цитата из документации: "Если вам не нужна мощь регулярных выражений, вы можете выбрать более быстрые (хоть и простые) альтернативы наподобие explode() или str_split()." split() c версии PHP 5.3.0 считается устаревшей. explode() таковой не считается. К слову в движках, фреймворках вызов 2000 функций - не предел. |
мдауж... что-то у вас все заумно, есть же простые варианты в PHP:
function convertDate($string) {
$months = array('Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня', 'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря');
return date('j '.$months[date('n', strtotime($string)) - 1].' Yг. в H:i', strtotime($string));
}
echo convertDate('2013-04-02 11:22:00');
|
devote, а Вы можете помочь мне написать такую ф-цию.
Есть например переменная $timezone - часовой пояс, от -11 до 11, её значение у каждого пользователя разное, в зависимости от того, какой часовой пояс пользователь выбрал при регистрации. Часовой пояс на сервере: UTC-4 (как в Нью-Йорке). Нужно, чтобы ф-ция возвращала строку вида '15 Апреля 2013 г. в 10:00', а если число сегодняшнее, то возвращало 'Сегодня в 10:00', или если число вчерашнее: 'Вчера в 10:00'. Время должно соответствовать часому поясу выбраного пользователям. Тоесть: если на сервере часовой пояс -4, то к времени нужно прибавить 4 часа + часовой пояс пользователя. Как-то так. Входящая строка в ф-цию выглядит следующим образом: 2013-04-02 11:22:00. Буду очень благодарен за такую ф-цию! Я то сам могу такую написать, но у меня она выйдет не так как у Вас, у меня она будет сделана криво и выполняться дольше. |
function convertDate($string, $timezone = 'UTC') {
$months = array(
'Января','Февраля', 'Марта', 'Апреля', 'Мая', 'Июня',
'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря'
);
$time = strtotime($string);
$timeZoneShift = ($time - strtotime($string.' '.$timezone));
$currentTime = time() + $timeZoneShift;
$time = $time + $timeZoneShift;
$firstToken = $time - strtotime('00:00:00', $currentTime) >= 0
? 'Сегодня' : ($time - strtotime('-1 day 00:00:00', $currentTime) >= 0
? 'Вчера' : 'j '.$months[date('n', $time) - 1].' Yг.');
return date($firstToken.' в H:i', $time);
}
echo convertDate('2013-04-23 15:59:59', 'GMT+4');
вторым параметром, временная зона пользователя |
devote, во, спасибо большое! А при вывове это ф-ции 100 раз например, большой нагрузки на сервер не будет?
|
Цитата:
|
| Часовой пояс GMT +3, время: 00:16. |