str_replace в кодировке utf-8

InviS

Новичок
str_replace в кодировке utf-8

Ребят, использую кодировку utf-8, хотел написать расширение для класса DateTime, но не знаю как делать замену строк в кодировке utf-8.
PHP:
<?
    class DateTimeRussian extends DateTime{
	public function format($format){
		$english = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
		$russian = array("Понедельник","Вторник","Среда","Четверг","Пятница","Суббота","Воскресенье");
		return str_replace($english, $russian, parent::format($format));
	}
    }
	$dateObj = new DateTimeRussian();
	echo $dateObj->format("l");
?>
в итоге получаю:


Кто как решал такую проблему?
 

iamFake

Mind Of Liberty
str_replace работает с однобайтовыми кодировками, русский в ютф8 - это уже 2 байта... multibyte, iconv...
 

InviS

Новичок
Я знаю, поэтому и спросил. mb_str_replace же не существует. А iconv - только зная кодировку. К примеру, если мне нужно будет заменять строки, но я не знаю кодировки? К примеру, немецкий язык, или же чешский. Тогда
PHP:
iconv("utf-8","windows-1251",$str);
не прокатит... что делать в таком случае?
 

iamFake

Mind Of Liberty
немецкий, чешский... да хоть симплифед чайна - ютф8 по барабану какой язык... а для интернациолизации есть специальные экстеншены, например intl
 

InviS

Новичок
не понял ничего.. Ну к примеру у меня в проекте есть русский и немецкий... И как мне сделать для немецкой кодировки вот такой вот трюк? С подменой даты...
 

fixxxer

К.О.
Партнер клуба
Тебе других функций мало?

Ну например можно так - join($to, preg_split("/$from/u", $str))
 

InviS

Новичок
fixxxer, А можно как-то пояснить? Или пример какой-нибудь простенький? Порыл ф-ции, что вы упомянули - ничего не понял, что делает данная строка кода
 

fixxxer

К.О.
Партнер клуба
Разбивает по сепаратору == что заменить и склеивает по тому на что заменить.

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

InviS

Новичок
fixxxer
С использованием strtr - вернуло то же самое, что и было.. ну по ходу =) Квадратики
PHP:
<?
			class DateTimeRussian extends DateTime{
				public function format($format){
					$trans = array(	"Monday"=>"Понедельник",
									"Tuesday"=>"Вторник",
									"Wednesday"=>"Среда",
									"Thursday"=>"Четверг",
									"Friday"=>"Пятница",
									"Saturday"=>"Суббота",
									"Sunday"=>"Воскресенье");
					return strtr(parent::format($format),$trans);
				}
			}
?>
 

fixxxer

К.О.
Партнер клуба
PHP:
~$ cat 1.php
<?php
class DateTimeRussian extends DateTime{
    public function format($format){
        $trans = array( "Monday"=>"Понедельник",
        "Tuesday"=>"Вторник",
        "Wednesday"=>"Среда",
        "Thursday"=>"Четверг",
        "Friday"=>"Пятница",
        "Saturday"=>"Суббота",
        "Sunday"=>"Воскресенье");
        return strtr(parent::format($format),$trans);
    }
}

$DT = new DateTimeRussian;
print $DT->format('l jS F Y h:i:s A');
~$ php 1.php
Суббота 23rd October 2010 10:28:31 AM
ЧЯДНТ?
 

InviS

Новичок
хм, оказывается был какой-то бок с кодировкой. Заработал и ваш способ и то, что я еще в первом посте написал также работает.. не знаю как, правда, ведь русские символы реально 2 байта занимают..
 

fixxxer

К.О.
Партнер клуба
Для замены нет никакой разницы между заменой "a" на "bcd" и заменой "a" на "я". Проблемы возникают только в случаях, когда заменяется набор байтов, оказавшихся на пересечении разных глифов. При использовании strtr для кодировки utf8 мне такое кажется невозможным (а для замены латиницы на русские и вcяко пофигу - вот если бы ты с китайского на русский, скажем, менял...), но это навскидку.
 

InviS

Новичок
так получается ф-ции mb_str_replace нет потому, что и str_replace отлично работает с кодировкой utf-8?
 

fixxxer

К.О.
Партнер клуба
Видимо, да. Хотя, скажем, с UCS2 проблемы быть могут запросто.
 

InviS

Новичок
Спасибо, буду пробовать. Хочу на UTF-8 перейти полностью. Пока тяжеловато...
 

fixxxer

К.О.
Партнер клуба
Все уже давно перешли :) Проблем, на самом деле, немного, главное, помнить, что 1 байт != 1 символ.
 

phprus

Moderator
Команда форума
fixxxer
Функцией str_replace можно заменять в строках в кодировке UTF-8, так как кодировка UTF-8 использует префиксное кодирование.
 

fixxxer

К.О.
Партнер клуба
ну я про то же.

strtr просто потому что в данной задаче str_replace это бессмысленное гоняние с начала строки на каждую итерацию.

про preg_split я сначала херню написал, да)
 

Вурдалак

Продвинутый новичок
fixxxer, а ты посмотри на алгоритм strtr(). К примеру,
PHP:
<?php

header('Content-type: text/plain; charset=utf-8');

$engNames = array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday');
$rusNames = array('Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье');

$rep_pairs = array_combine($engNames, $rusNames);

$source = 'Saturday 23rd October 2010 10:28:31 AM';

$t = microtime(true);

for($i = 0; $i < 1000; $i++) {
    $s = strtr($source, $rep_pairs);
}

var_dump(microtime(true) - $t);

$t = microtime(true);

for($i = 0; $i < 1000; $i++) {
    $s = str_replace($engNames, $rusNames, $source);
}

var_dump(microtime(true) - $t);
даёт такие результаты (несколько замеров):
Код:
float(0.00959801673889)
float(0.00891399383545)
Код:
float(0.00983119010925)
float(0.0109660625458)
Код:
float(0.00957798957825)
float(0.00594711303711)
Код:
float(0.00954413414001)
float(0.00735306739807)
Код:
float(0.00880694389343)
float(0.00922393798828)
Т.е. в большинстве случаев на моём компе быстрее вариант с str_replace().

Чем длиннее исходная строка и чем больше разница длин самой короткой заменяемой подстроки и самой длинной, то тем больше str_replace() выглядит лучше на фоне strtr().
 
Сверху