>  기사  >  백엔드 개발  >  PHP에서 정보 형식화 작업을 배우는 방법

PHP에서 정보 형식화 작업을 배우는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-07-02 15:15:142179검색

국제 구성요소를 학습하는 과정에서 우리는 이미 NumberFormatter의 숫자 형식 지정 작업을 접해 보았습니다. 이를 통해 숫자를 표준 형식, 통화, 현지 언어 등으로 변환할 수 있습니다. 오늘은 정보 포맷팅에 특별히 사용되는 또 다른 클래스인 MessageFormatter에 대해 알아보겠습니다. 주로 문자열 연산에 사용됩니다.

PHP에서 정보 형식화 작업을 배우는 방법

MessageFormatter도 ICU 사양을 따르며, 맨 아래 레이어는 C에서의 ICU 연산이므로 C 관련 코드의 사용법에는 큰 차이가 없습니다.

형식

// 格式化
$fmt = new MessageFormatter("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子");
echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL;
// 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子

$fmt = new MessageFormatter("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum");
echo $fmt->format([4560, 123, 4560 / 123]), PHP_EOL;
// 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum

echo MessageFormatter::formatMessage("zh_CN", "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子", [4560, 123, 4560 / 123]), PHP_EOL;
// 4,560 只猴子在 123 颗树上,每只树上有 37.073 只猴子

echo MessageFormatter::formatMessage("de", "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", [4560, 123, 4560 / 123]), PHP_EOL;
// 4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum

보셨나요? PDO의 사전 컴파일 작업을 위한 자리 표시자와 유사합니다. format() 메서드를 호출한 후 이 메서드의 매개변수가 자리 표시자의 내용을 대체하도록 할 수 있습니다.

자리 표시자에 사용되는 매개 변수 유형과 위치를 지정할 수 있습니다. {매개 변수 아래 첨자, 유형, 확장 유형} 이는 이 정보 데이터 형식 지정에 대한 자리 표시자의 규칙 정의입니다. 매우 간단해 보이지만 실제로는 더 많은 기능이 있습니다. 이에 대해서는 나중에 살펴보겠습니다.

단, 기사 마지막에 있는 참조 링크에서 공식 문서를 확인할 수 있습니다.

MessageFormatter::formatMessage() 이 정적 메소드는 인스턴스화한 후 format() 메소드를 호출할 필요 없이 언어, 준비된 명령문 및 대체 매개변수를 한 번에 지정할 수 있습니다.

Deformat(규칙에 따라 매개변수 배열 가져오기)

형식을 지정할 수도 있습니다. 물론 해당 자리 표시자의 매개변수 목록을 얻기 위해 명령문 규칙에 따라 관련 문자열을 변형할 수도 있습니다.

// 根据格式化规则反向获取规则参数
$fmt = new MessageFormatter('zh_CN', "{0,number,integer} 只猴子在 {1,number,integer} 颗树上,每只树上有 {2,number} 只猴子");
$res = $fmt->parse("4,560 只猴子在 123 树上,每只树上有 37.073 只猴子");
var_export($res); // false
echo "ERROR: " . $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n";
// ERROR: Parsing failed: U_MESSAGE_PARSE_ERROR (6)

$fmt = new MessageFormatter('en_US', "{0,number,integer} monkeys on {1,number,integer} trees make {2,number} monkeys per tree");
$res = $fmt->parse("4,560 monkeys on 123 trees make 37.073 monkeys per tree");
var_export($res);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )

$fmt = new MessageFormatter('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum");
$res = $fmt->parse("4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum");
var_export($res);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )

$fmt = MessageFormatter::parseMessage('de', "{0,number,integer} Affen auf {1,number,integer} Bäumen sind {2,number} Affen pro Baum", "4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum");
var_export($fmt);
// array (
//     0 => 4560,
//     1 => 123,
//     2 => 37.073,
//   )

인스턴스화된 구문 분석() 메서드를 사용하거나 정적 메서드인 MessageFormatter::parseMessage()를 직접 사용하면 이러한 작업을 수행할 수 있습니다.

중국어 로캘인 zh_CN의 경우 이 작업으로 인해 문제가 발생할 수 있다는 점에 유의해야 합니다. getErrorMessage(), getErrorCode()를 통해 에러 메시지와 에러 코드를 확인할 수 있는데, 중국어의 경우 에러 메시지가 바로 파싱에 실패했다는 것을 알 수 있습니다.

획득 규칙 설정

인스턴스화된 개체에서 규칙 문을 동적으로 수정할 수도 있습니다.

// 设置获取规则
$fmt = new MessageFormatter("zh_CN", "{0, number} 猴子在 {1, number} 颗树上");
echo "默认规则: '" . $fmt->getPattern(), PHP_EOL; // 默认规则: '{0, number} 猴子在 {1, number} 颗树上'
echo "格式化结果:" . $fmt->format(array(123, 456)), PHP_EOL; // 格式化结果:123 猴子在 456 颗树上

$fmt->setPattern("{0, number} 颗树上有 {1, number} 猴子");
echo "新规则: '" . $fmt->getPattern(), PHP_EOL; // 新规则: '{0, number} 颗树上有 {1, number} 猴子'
echo "新规则格式化结果: " . $fmt->format(array(123, 456)), PHP_EOL; // 新规则格式化结果: 123 颗树上有 456 猴子

두 가지 매우 간단한 메서드인 setPattern()은 현재 인스턴스화에 해당하는 형식 지정 규칙을 설정하는 데 사용되고, getPattern()은 현재 인스턴스화 개체의 형식 지정 규칙을 가져오고 보는 데 사용됩니다. 새로운 규칙을 설정한 후에는 새로운 규칙 문에 따라 format() 또는parse()가 실행됩니다.

형식 지정의 전체 예

위에서 언급한 것처럼 숫자 외에 날짜 형식에 대한 자리 표시자가 있을 수도 있습니다. 이를 시연해 보겠습니다.

echo MessageFormatter::formatMessage('zh_CN', '今天是 {3, date, full},当前时间为 {3, time, ::Hms}, 我要准备开始 {0} 了,今天要和 {2,number,integer} 人见面,还不能忘了要交 {1,number,currency} 元的电费', ['上班', 35.33, 25, new DateTime()]), PHP_EOL;
// 今天是 2020年11月16日星期一,当前时间为 10:09:30, 我要准备开始 上班 了,今天要和 25 人见面,还不能忘了要交 ¥35.33 元的电费

이 명령문에서 우리가 제공하는 매개변수의 순서는 명령문에 나타나는 자리표시자의 순서와 일치하지 않습니다. 이는 해당 위치에 매개변수 배열 첨자를 지정하기만 하면 됩니다. first { 3, date, full}은 매개변수 배열의 4번째 요소(0부터 시작)를 지정합니다.

날짜 유형과 시간 유형은 모두 지정할 수 있는 유형입니다. 물론 날짜 형식도 지정할 수 있습니다. 예를 들어 두 번째 자리 표시자의 경우 현재 시간, 분, 초 정보만 표시합니다.

문자열 정보라면 간단한 {0}만 있으면 됩니다. 문자열에는 너무 많은 유형 설정이 필요하지 않습니다. 숫자 유형은 이전에 설명한 NumberFormatter에서 지정할 수 있는 유형과 마찬가지로 통화 및 기타 유형으로 직접 형식화할 수 있습니다.

이 예제를 읽은 후 이 MessageFormatter의 강력함을 느끼셨나요? 걱정하지 마세요. 훨씬 더 멋진 기능이 있습니다.

매개변수 내용에 따른 복수형 표시

복수형의 경우 중국어 문법에는 실제로 그런 표현이 없습니다. 예를 들어 고양이 한 마리는 고양이이고 두 마리는 고양이입니다.

echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [0]),PHP_EOL; // I Have no cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [1]),PHP_EOL; // I Have a cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [2]),PHP_EOL; // I Have 2 cats

매개변수 유형에서 복수형은 복수형을 의미하지만 실제로는 switch() 문의 사용법으로 생각할 수 있습니다. 숫자

echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [0]),PHP_EOL; // 我没有猫
echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [1]),PHP_EOL; // 我有 1 只猫
echo MessageFormatter::formatMessage('zh_CN', '我{0, plural, =0{没有猫} other{有 # 只猫}}', [2]),PHP_EOL; // 我有 2 只猫

#는 해당 매개변수 값의 원래 내용입니다. 이 구문 세트는 MessageFormatter 클래스를 더 높은 수준으로 끌어올립니다. 먼저 이 문제를 살펴보겠습니다.

echo MessageFormatter::formatMessage('en_US', 'I Have {0, plural, =0{no cat} =1{a cat} other{# cats}}', [-1]),PHP_EOL; // I Have -1 cats

매개변수가 잘못 전달되었습니다. -1 cat이 잘못되었습니다. 그렇죠? 문제가 되지 않습니다. 이 문제를 해결할 수 있는 다른 방법이 있습니까?

선택 조건 규칙

// 选择表达式
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [-1]),PHP_EOL; // I Have no cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [0]),PHP_EOL; // I Have no cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [1]),PHP_EOL; // I Have one cat
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [2]),PHP_EOL; // I Have 2 cats
echo MessageFormatter::formatMessage('en_US', 'I Have {0, choice, 0 #no cats| 1 #one cat | 2 #{0, number} cats}', [10]),PHP_EOL; // I Have 10 cats

choice 선택과 관련된 문법임을 단어 선택을 보면 알 수 있습니다. 다음 매개변수는 실제로 =2 범위 내에서 사용되는 콘텐츠를 나타내는 간격입니다. 또한 자리 표시자 규칙에는 자리 표시자 기호도 포함될 수 있습니다.

요약

다시 한번 눈을 뜨게 되었습니다. 실제로 기사의 처음 두 부분에는 놀라운 내용이 없습니다. 결국 일반적인 문자열 교체가 가능하지만 뒤로 갈수록 점점 더 흥미로워집니다.

물론 관련 규칙 구문이 더 있어야 하지만 이에 대한 정보는 PHP 공식 문서나 ICU 공식 문서 모두에서 많이 소개되지 않습니다.

그래서 우리는 여전히 그런 것이 있다는 것을 먼저 배우고 이해하는 태도를 취합니다. 앞으로는 공유하고 배우기 전에 더 흥미로운 정보를 찾아보도록 하겠습니다. 함께 토론해보세요!

추천 학습: php 비디오 튜토리얼

위 내용은 PHP에서 정보 형식화 작업을 배우는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제