Эффективно извлекать значение из мета-тегов, заданных в PHP как строка - PullRequest
0 голосов
/ 01 октября 2018

У меня есть пара метатегов, хранящихся в строке.Вот пример:

<meta property="article:published_time" content="2018-04-08T09:00:01+00:00" />
<meta property="article:modified_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:updated_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:image" content="http://link-to-the-image.jpg" />
<meta property="og:image:secure_url" content="https://link-to-the-image.jpg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Alt value for the Article Image" />

Есть много других таких тегов, но меня интересует только получение значения og:updated_time.Когда у меня есть значение, мне нужно сравнить его с каким-то другим значением и, в случае необходимости, заменить исходную временную метку новым оценщиком.

Я могу использовать preg_replace_callback, но это будет очень беспорядочноизвлечь значение og:updated_time и article:modified_time.Есть ли более чистый и простой способ сделать то же самое?

Это единственное значение, которое мне нужно извлечь.Не будет ли проще сделать это, используя какие-то манипуляции со строками вместо того, чтобы сначала преобразовывать строку в HTML?

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Преобразование этих тегов в HTML

Эти теги уже являются HTML, поэтому преобразование не выполняется.

Вы можете использовать domdocument, чтобы получить элемент, который вам нужен, вот так:

$html = '<meta property="article:published_time" content="2018-04-08T09:00:01+00:00" />
<meta property="article:modified_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:updated_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:image" content="http://link-to-the-image.jpg" />
<meta property="og:image:secure_url" content="https://link-to-the-image.jpg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Alt value for the Article Image" />';
$dom = new domdocument();
$dom->loadhtml($html);
$metas = $dom->getelementsbytagname('meta');
foreach($metas as $meta) {
    if($meta->getattribute('property') == 'og:updated_time') {
        echo $meta->getattribute('content');
    }
}

https://3v4l.org/SeiMe

Вы также можете использовать xpath для его упрощения (если вы считаете xpath более простым).

$dom = new domdocument();
$dom->loadhtml($html);
$xpath = new DOMXPath($dom);
echo $xpath->evaluate('//meta[@property="og:updated_time"]/@content')[0]->nodeValue;

https://3v4l.org/fFFuT

0 голосов
/ 02 октября 2018

Хотя регулярное выражение в этом случае может быть совершенно стабильным для вашей очень предсказуемой коллекции мета-тегов, мы хотели бы порекомендовать DomDocument для стабильности.Я также рекомендую XPath для простоты доступа к элементам.

Код: ( Демо )

$html = <<<HTML
<meta property="article:published_time" content="2018-04-08T09:00:01+00:00" />
<meta property="article:modified_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:updated_time" content="2018-10-01T07:33:20+00:00" />
<meta property="og:image" content="http://link-to-the-image.jpg" />
<meta property="og:image:secure_url" content="https://link-to-the-image.jpg" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:image:alt" content="Alt value for the Article Image" />
HTML;

$dom = new DOMDocument; 
$dom->loadHTML($html,  LIBXML_HTML_NODEFDTD);  // omit unwanted doctype tags, but allow <html> for output readability
$xpath = new DOMXPath($dom);

$modified_node = $xpath->query('//meta[@property="article:modified_time"]')[0];
$modified_value = $modified_node->getAttribute('content');
$updated_node = $xpath->query('//meta[@property="og:updated_time"]')[0];
$updated_value = $updated_node->getAttribute('content');

/*
if (convert($user_value) > convert($modified_time) || convert($user_value) > convert($updated_time)) {
*/
    $modified_node->setAttribute('content', 'fresh');
    $updated_node->setAttribute('content', 'new');
/* } */

echo $dom->saveHTML();

Вывод:

<html><head><meta property="article:published_time" content="2018-04-08T09:00:01+00:00">
<meta property="article:modified_time" content="fresh">
<meta property="og:updated_time" content="new">
<meta property="og:image" content="http://link-to-the-image.jpg">
<meta property="og:image:secure_url" content="https://link-to-the-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Alt value for the Article Image"></head></html>

Теперь этодобавляет теги <html><head> и </head></html> (потому что они отсутствовали в вашем вводном примере), но я представляю, что они уже присутствуют в вашей фактической разметке.

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

Мое решение использует два запроса xpath для нацеливания на два требуемых элемента метатега, а затем извлекает значение атрибута content из каждого, чтобы вы могливыполнить свою логику сравнения.Если данные соответствуют требованиям, тогда для новых значений атрибута content задаются желаемые значения.

Вызовите saveHTML(), чтобы увидеть обновленную HTML-структуру.

0 голосов
/ 01 октября 2018

Если вы абсолютно уверены в использовании регулярных выражений, вы можете сделать следующее и использовать захват группы 1:

<meta\s+property=\"og:updated_time\"\s+content=\"([^"]+)\"

Пример здесь: https://regex101.com/r/jK5wU3/8

...