【发布时间】:2015-08-14 18:10:19
【问题描述】:
我在这里找到了这个 slugify 函数:PHP function to make slug (URL string)
我尝试将其重写为 MySQL,我所做的是:
- 从https://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/借来的regex_replace函数
- 和音译函数来自:http://igstan.ro/posts/2009-02-13-mysql-transliteration-function.html
- 将上面提到的正确答案函数从symfony fw改写为mysql create函数的最后一位,function。
,但是在输出中我只得到了降低的文本,没有破折号和字母似乎也被音译,所以只剩下破折号了。
我的查询:
UPDATE `ad_kategorija` SET `slug_lt`=slugify(`kat_pavlt`), `slug_ru`=slugify(`kat_pavru`), `slug_en`=slugify(`kat_paven`)
功能:
# Regex Replace function
DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000)) RETURNS varchar(1000) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE temp VARCHAR(1000);
DECLARE ch VARCHAR(1);
DECLARE i INT;
SET i = 1;
SET temp = '';
IF original REGEXP pattern THEN
loop_label: LOOP
IF i>CHAR_LENGTH(original) THEN
LEAVE loop_label;
END IF;
SET ch = SUBSTRING(original,i,1);
IF NOT ch REGEXP pattern THEN
SET temp = CONCAT(temp,ch);
ELSE
SET temp = CONCAT(temp,replacement);
END IF;
SET i=i+1;
END LOOP;
ELSE
SET temp = original;
END IF;
RETURN temp;
END$$
# Transliteration function
CREATE DEFINER=`root`@`localhost` FUNCTION `transliterate`(original VARCHAR(512)) RETURNS varchar(512) CHARSET utf8
BEGIN
DECLARE translit VARCHAR(512) DEFAULT '';
DECLARE len INT(3) DEFAULT 0;
DECLARE pos INT(3) DEFAULT 1;
DECLARE letter CHAR(1);
DECLARE is_lower BIT;
SET len = CHAR_LENGTH(original);
WHILE (pos <= len) DO
SET letter = SUBSTRING(original, pos, 1);
SET is_lower = IF(LCASE(letter) COLLATE utf8_bin = letter COLLATE utf8_bin, 1, 0);
CASE TRUE
WHEN letter = 'a' THEN SET letter = IF(is_lower, 'a', 'A');
WHEN letter = 'b' THEN SET letter = IF(is_lower, 'b', 'B');
WHEN letter = 'c' THEN SET letter = IF(is_lower, 'c', 'C');
WHEN letter = 'd' THEN SET letter = IF(is_lower, 'd', 'D');
WHEN letter = 'e' THEN SET letter = IF(is_lower, 'e', 'E');
WHEN letter = 'f' THEN SET letter = IF(is_lower, 'f', 'F');
WHEN letter = 'g' THEN SET letter = IF(is_lower, 'g', 'G');
WHEN letter = 'h' THEN SET letter = IF(is_lower, 'h', 'H');
WHEN letter = 'i' THEN SET letter = IF(is_lower, 'i', 'I');
WHEN letter = 'j' THEN SET letter = IF(is_lower, 'j', 'J');
WHEN letter = 'k' THEN SET letter = IF(is_lower, 'k', 'K');
WHEN letter = 'l' THEN SET letter = IF(is_lower, 'l', 'L');
WHEN letter = 'ł' THEN SET letter = IF(is_lower, 'l', 'L');
WHEN letter = 'm' THEN SET letter = IF(is_lower, 'm', 'M');
WHEN letter = 'n' THEN SET letter = IF(is_lower, 'n', 'N');
WHEN letter = 'o' THEN SET letter = IF(is_lower, 'o', 'O');
WHEN letter = 'p' THEN SET letter = IF(is_lower, 'p', 'P');
WHEN letter = 'q' THEN SET letter = IF(is_lower, 'q', 'Q');
WHEN letter = 'r' THEN SET letter = IF(is_lower, 'r', 'R');
WHEN letter = 's' THEN SET letter = IF(is_lower, 's', 'S');
WHEN letter = 't' THEN SET letter = IF(is_lower, 't', 'T');
WHEN letter = 'u' THEN SET letter = IF(is_lower, 'u', 'U');
WHEN letter = 'v' THEN SET letter = IF(is_lower, 'v', 'V');
WHEN letter = 'w' THEN SET letter = IF(is_lower, 'w', 'W');
WHEN letter = 'x' THEN SET letter = IF(is_lower, 'x', 'X');
WHEN letter = 'y' THEN SET letter = IF(is_lower, 'y', 'Y');
WHEN letter = 'z' THEN SET letter = IF(is_lower, 'z', 'Z');
ELSE
SET letter = letter;
END CASE;
-- CONCAT seems to ignore the whitespace character. As a workaround we use
-- CONCAT_WS with a whitespace separator when the letter is a whitespace.
SET translit = CONCAT_WS(IF(letter = ' ', ' ', ''), translit, letter);
SET pos = pos + 1;
END WHILE;
RETURN translit;
END$$
# slug create function
CREATE DEFINER=`root`@`localhost` FUNCTION `slugify`(`dirty_string` VARCHAR(255) CHARSET utf8) RETURNS varchar(255) CHARSET utf8
DETERMINISTIC
BEGIN
DECLARE temp_string VarChar(255) DEFAULT '';
DECLARE output VarChar(255);
SET temp_string = regex_replace('~[^\\pL\\d]+~u', '-', dirty_string);
SET temp_string = TRIM(BOTH '-' FROM temp_string);
SET temp_string = transliterate(temp_string);
SET temp_string = LOWER(temp_string);
SET temp_string = regex_replace('~[^-\\w]+~', '', temp_string);
If temp_string = '' Then
SET temp_string = '';
End If;
SET output = temp_string;
Return output;
END$$
DELIMITER ;
所以有人可以帮我完成它,主要问题是我没有在空格上替换破折号,也许正则表达式是错误的。或者正则表达式替换功能需要一些插件来完成。请帮忙。
【问题讨论】:
-
出于好奇,你为什么要在 MySQL 中这样做?
-
@Mjh,所以我不需要编写一个写入模块,它会占用 10 个表的大块,将其放入数组中,将其 foreach 到另一个非常需要资源的 php 上的 slugify 代码并放入它回到mysql。我想声明这些函数会更容易,只需运行简单的更新命令来重写让我们说页面的标题到 slug。因此,您无需在每个页面上手动更改它。或者运行一些自定义 php db updater 脚本。希望这能满足你的好奇心。它主要用于通过控制台更改大量数据库。假设我的客户决定获取项目的 seo 网址。解释了吗?
-
嗯,我很佩服你的奉献精神,我会对 PHP 函数和通过它运行的东西感到满意。即使在 1000 万张唱片上,它仍然能够在一分钟左右的时间内完成。我只是想知道,因为你花了很多时间在这上面,我通常对这些事情太懒了,更喜欢更快的解决方案:)
-
在 1 分钟内完成 1000 万条记录。真的很想知道你的装备规格和mysql设置。 :-)
-
我使用的测试/播放设备是 2 个 samsung evo 850 在 raid 0、8gb 缓冲池、i5 @ 3.4 ghz。我将多个查询排队,因此我不会立即花费所有驱动器的 I/O,尊重驱动器的带宽。这样一来,所有的查询都很快,几千万条记录基本算不了什么。
标签: php mysql regex function slug