PHP клонирование объекта приводит к более чем одному объекту? - PullRequest
1 голос
/ 28 июля 2011

Сначала я покажу код:

//item duplication code goes here
elseif($_REQUEST['action'] == 'duplicate'){
    $array_index = $_REQUEST['array_index'];
    $cart = $_SESSION['cart'];
    $tempItem = clone $cart[$array_index];
    $cart[]=$tempItem;
    $_SESSION['cart'] = $cart;
}

Например, если у меня есть 1 товар в корзине, нажатие на ссылку даст мне 2 одинаковых. Дело в том, что немедленный результат верный (я открываю ссылку в новой вкладке), но после обновления страницы (старая вкладка) она дает мне 3.

Чтобы объяснить, смотрите короткое видео:

http://www.youtube.com/watch?v=OORcT5KxZqw

Я действительно не понимаю, почему это происходит. Любая помощь приветствуется!

Ответы [ 3 ]

1 голос
/ 28 июля 2011

Что вы делаете со своим кодом, так это то, что если $_REQUEST из action равно значению duplicate, то вы делаете следующие вещи:

  1. получить корзину из сеанса (который ранее был сохранен)
  2. клонируйте корзину и сохраните ее при температуре
  3. , а затем скопировать обратно темп в корзину
  4. и, наконец, сохранить корзину в сеансе
  5. Тогда, я полагаю, вы где-то показываете свою карту ...

То, что здесь происходит, заключается в том, что инструкции по клонированию должны быть действительными только при нажатии на дублирующуюся ссылку. Я предполагаю, что ваш PHP находится в том же файле, что и HTML, поэтому, когда вы открываете его в новом окне, корзина обновляется на 2 элемента и сохраняется в сеансе (что является общим для всех экземпляров вашей страницы), а также при перезагрузке вашей страницы те же 2 предмета извлекаются из сеанса и показываются вам. Также здесь вы должны заметить, что $_REQUEST['action'] все еще присутствует, поэтому он дублирует еще 1 элемент. Теперь, когда вы обновляете страницу, она будет дублировать еще 1 элемент.

В качестве решения этой проблемы попробуйте отменить действие с помощью функции unset() после того, как вы клонировали корзину, так что php запускается только при необходимости.

0 голосов
/ 28 июля 2011

Поскольку $ _ REQUEST также содержит $ _ GET , я предполагаю, что ваш &action=duplicate находится в URL, и ваш код выполняется так же часто, как вы перезагружаете страницу.

Я бы предложил перенаправить (используя header('Location: ...');, см .: header ) после дублирования, но только после удаления action -var из url.

Обновление :

Использование функции getUrlCurrently Вот краткий пример:

function getUrlCurrently($filter = array()) {
    $pageURL = isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on" ? "https://" : "http://";

    $pageURL .= $_SERVER["SERVER_NAME"];

    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= ":".$_SERVER["SERVER_PORT"];
    }

    $pageURL .= $_SERVER["REQUEST_URI"];


    if (strlen($_SERVER["QUERY_STRING"]) > 0) {
        $pageURL = rtrim(substr($pageURL, 0, -strlen($_SERVER["QUERY_STRING"])), '?');
    }

    $query = $_GET;
    foreach ($filter as $key) {
        unset($query[$key]);
    }

    if (sizeof($query) > 0) {
        $pageURL .= '?' . http_build_query($query);
    }

    return $pageURL;
}

if ($_REQUEST['action'] == 'duplicate'){
    // your duplication code here ...

    // after the duplication
    header('Location: ' . getUrlCurrently(array(
        'action', 'array_index' // <--- unsetting the problematic url-vars
    )));
    exit();
}
0 голосов
/ 28 июля 2011

Я подозреваю, что это дает вам три, когда вы обновляете страницу, потому что старый $_REQUEST['array_index'] все еще болтается.Вам необходимо установить переменную сеанса, чтобы указать, что действие было завершено, и проверить его, прежде чем приступить к выполнению этого действия.

elseif($_REQUEST['action'] == 'duplicate'){

    // Check if you already duplicated this array_index
    if (!isset($_SESSION['duplication_done']) || (isset($_SESSION['duplication_done']) &&  $_SESSION['duplication_done'] != $_REQUEST['array_index']) {
      $array_index = $_REQUEST['array_index'];
      $cart = $_SESSION['cart'];
      $tempItem = clone $cart[$array_index];
      $cart[]=$tempItem;
      $_SESSION['cart'] = $cart;

      // After duplicating, store this array_index in $_SESSION
      $_SESSION['duplication_done'] = $_REQUEST['array_index'];
    }
}
...