PHP: конвертировать строку объекта javascript в массив php - PullRequest
0 голосов
/ 17 апреля 2019

Я получаю HTML-код одной страницы через phpQuery, а затем получаю строковый код из тега script в голове через php regex:

var BASE_DATA = {
userInfo: {
  id: 0,
  userName: 'no-needed',
  avatarUrl: 'no-needed',
  isPgc: false,
  isOwner: false
},
headerInfo: {
  id: 0,
  isPgc: false,
  userName: 'no-needed',
  avatarUrl: 'no-needed',
  isHomePage: false,
  crumbTag: 'no-needed',
  hasBar: true
},
articleInfo: 
{
  title: 'needed',
  content: 'needed',
  groupId: 'needed',
  itemId: 'needed',
  type: 1,
  subInfo: {
    isOriginal: false,
    source: 'needed',
    time: 'needed'
  },
  tagInfo: {
    tags: [{"name":"no-needed 1"},{"name":"no-needed 2"},{"name":"no-needed 3"}],
    groupId: 'no-needed',
    itemId: 'no-needed',
    repin: 0,
  },
  has_extern_link: 0,
  coverImg: 'no-needed'
},
commentInfo:
{
  groupId: 'no-needed',
  itemId: 'no-needed',
  comments_count: 151,
  ban_comment: 0
},};

Я хочу преобразовать эту строку в массив php, например:

$base_data = array(
'articleInfo' => array(
    'title' => 'needed',
    'content' => 'needed',
    'groupId' => 'needed',
    'itemId' => 'needed',
    'subInfo' => array(
        'source' => 'needed',
        'time' => 'needed',
    ),
));

или

$base_data = array(
'title' => 'needed',
'content' => 'needed',
'groupId' => 'needed',
'itemId' => 'needed',
'subInfo' => array(
    'source' => 'needed',
    'time' => 'needed',
),);

Я уже пытался многими способами, такими как: json_decode, получать содержимое из фигурных скобок через php regex и функцию preg_match_all. Но все они работают не очень хорошо.

Я пробовал два способа:

первый путь:

$json = str_ireplace(array('var BASE_DATA =', '};'), array('', '}'), $js);
json_decode($json, true);

второй путь:

preg_match_all('/\{([^}]+)\}/', $js, $matches);
print_r($matches[1]);

или

preg_match_all('/articleInfo:\s*\{([^}]+)\}/', $script_text, $matches);
print_r($matches[1][0]);

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

Я даже хотел использовать движок V8 JavaScript, но .....

Кто-нибудь знает лучший способ закончить его, пожалуйста?

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Мне пришлось переформатировать ваш JSON, который был недействительным (проверено на https://jsonlint.com/).

Я добровольно использовал несколько функций str_replace (), чтобы вы лучше понимали процесс, однако вы можете оптимизировать приведенный ниже код, сделав несколько замен одновременно в одном и том же str_replace ().

Это работает:

<?php

$to_decode = "var BASE_DATA = {
userInfo: {
  id: 0,
  userName: 'no-needed',
  avatarUrl: 'no-needed',
  isPgc: false,
  isOwner: false
},
headerInfo: {
  id: 0,
  isPgc: false,
  userName: 'no-needed',
  avatarUrl: 'no-needed',
  isHomePage: false,
  crumbTag: 'no-needed',
  hasBar: true
},
articleInfo: 
{
  title: 'needed',
  content: 'needed',
  groupId: 'needed',
  itemId: 'needed',
  type: 1,
  subInfo: {
    isOriginal: false,
    source: 'needed',
    time: 'needed'
  },
  tagInfo: {
    tags: [{\"name\":\"no-needed 1\"},{\"name\":\"no-needed 2\"},{\"name\":\"no-needed 3\"}],
    groupId: 'no-needed',
    itemId: 'no-needed',
    repin: 0,
  },
  has_extern_link: 0,
  coverImg: 'no-needed'
},
commentInfo:
{
  groupId: 'no-needed',
  itemId: 'no-needed',
  comments_count: 151,
  ban_comment: 0
},};";

/* Clean JSON and encapsulate in brackets */
$to_decode = str_replace('var BASE_DATA = {', '', $to_decode);
$to_decode = '{'.substr($to_decode, 0, -3).'}';

/* Remove spaces, tabs, new lines, etc. */
$to_decode = str_replace(' ', '', $to_decode);
$to_decode = str_replace("\n", '', $to_decode);
$to_decode = str_replace("\t", '', $to_decode);
$to_decode = str_replace("\r", '', $to_decode);

/* Encapsulate keys with quotes */
$to_decode = preg_replace('/([a-z_]+)\:/ui', '"{$1}":', $to_decode);
$to_decode = str_replace('"{', '"', $to_decode);
$to_decode = str_replace('}"', '"', $to_decode);
$to_decode = str_replace('\'', '"', $to_decode);

/* Remove unecessary trailing commas */
$to_decode = str_replace(',}', '}', $to_decode);

echo '<pre>';
var_dump(json_decode($to_decode));

Результат с использованием print_r:

(для ясности я добавил true / false, в противном случае они будут показаны только с использованием var_dump ())

stdClass Object
(
    [userInfo] => stdClass Object
        (
            [id] => 0
            [userName] => no-needed
            [avatarUrl] => no-needed
            [isPgc] => false
            [isOwner] => false
        )

    [headerInfo] => stdClass Object
        (
            [id] => 0
            [isPgc] => false
            [userName] => no-needed
            [avatarUrl] => no-needed
            [isHomePage] => false
            [crumbTag] => no-needed
            [hasBar] => true
        )

    [articleInfo] => stdClass Object
        (
            [title] => needed
            [content] => needed
            [groupId] => needed
            [itemId] => needed
            [type] => 1
            [subInfo] => stdClass Object
                (
                    [isOriginal] => false
                    [source] => needed
                    [time] => needed
                )

            [tagInfo] => stdClass Object
                (
                    [tags] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [name] => no-needed1
                                )

                            [1] => stdClass Object
                                (
                                    [name] => no-needed2
                                )

                            [2] => stdClass Object
                                (
                                    [name] => no-needed3
                                )

                        )

                    [groupId] => no-needed
                    [itemId] => no-needed
                    [repin] => 0
                )

            [has_extern_link] => 0
            [coverImg] => no-needed
        )

    [commentInfo] => stdClass Object
        (
            [groupId] => no-needed
            [itemId] => no-needed
            [comments_count] => 151
            [ban_comment] => 0
        )

)
0 голосов
/ 17 апреля 2019

спасибо @Bruno Leveque за вашу идею.

Я отредактировал ваш код, как показано ниже, чтобы он работал хорошо:

  1. Я изменил $to_decode = str_replace(' ', '', $to_decode); на $to_decode = preg_replace('/[\n| |\s]{2,}/',' ',$to_decode);, это означает, что все 1+ пробел будет заменен на 1 пробел.потому что иногда нам нужно пространство, например: content: '

  2. Я добавил $to_decode = str_replace("'", '"', $to_decode); перед тем, как ваш комментарий код /* Encapsulate keys with quotes */

  3. изменился $to_decode = preg_replace('/([a-z_]+)\:/ui', '"{$1}":', $to_decode); на $to_decode = preg_replace('/([a-z_]+)\: /ui', '"$1":', $to_decode); (там еще один пробел);и прокомментировал //$to_decode = str_replace('"{', '"', $to_decode); и //$to_decode = str_replace('}"', '"', $to_decode);

  4. добавил еще один код: $to_decode = str_replace(", }", '}', $to_decode);

, поэтому мой окончательный код: enter image description here

, потому что @Bruno Leveque не знает точно, что именно "нужно" и "не нужно", поэтому спасибо за идею.

, похоже, не идеальный способ....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...