2017-09-21 1 views
1

基本的なショッピングカートを使用して基本サイトをまとめています。今後、セッションに機密情報を保存する予定です。 。PHPショッピングカートセッションは、カスタムセッションハンドラがサイトに組み込まれた後に更新されません

function decrypt($edata, $password) { 
$data = base64_decode($edata); 
$salt = substr($data, 0, 16); 
$ct = substr($data, 16); 

$rounds = 3; // depends on key length 
$data00 = $password.$salt; 
$hash = array(); 
$hash[0] = hash('sha256', $data00, true); 
$result = $hash[0]; 
for ($i = 1; $i < $rounds; $i++) { 
    $hash[$i] = hash('sha256', $hash[$i - 1].$data00, true); 
    $result .= $hash[$i]; 
} 
    $key = substr($result, 0, 32); 
    $iv = substr($result, 32,16); 

    return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv); 

    } 

    function encrypt($data, $password) { 

// Set a random salt 
$salt = openssl_random_pseudo_bytes(16); 
$salted = ''; 
$dx = ''; 
// Salt the key(32) and iv(16) = 48 
while (strlen($salted) < 48) { 
    $dx = hash('sha256', $dx.$password.$salt, true); 
    $salted .= $dx; 
} 

$key = substr($salted, 0, 32); 
$iv = substr($salted, 32,16); 

$encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv); 
return base64_encode($salt . $encrypted_data); 

} 

class SecureSessionHandler extends SessionHandler { 

protected $name, $cookie; 
private $key; 

public function __construct($key, $name = 'MY_SESSION', $cookie = []) 
     { 
    $this->key = $key; 
    $this->name = $name; 
    $this->cookie = $cookie; 
    $this->cookie += [ 
     'lifetime' => 0, 
     'path'  => ini_get('session.cookie_path'), 
     'domain' => ini_get('session.cookie_domain'), 
     'secure' => isset($_SERVER['HTTPS']), 
     'httponly' => true 
    ]; 
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256- 
    cbc')); 
    $this->setup(); 
} 
private function setup() 
{ 
    ini_set('session.use_cookies', 1); 
    ini_set('session.use_only_cookies', 1); 
    session_name($this->name); 
    session_set_cookie_params(
     $this->cookie['lifetime'], 
     $this->cookie['path'], 
     $this->cookie['domain'], 
     $this->cookie['secure'], 
     $this->cookie['httponly'] 
    ); 

} 

public function start() 
{ 
    if (session_id() === '') { 
     if (session_start()) { 
      return mt_rand(45, 99) === 55 ? $this->refresh() : true; // 1/5 
     } 
    } 
    return false; 
} 

public function forget() 
{ 
    if (session_id() === '') { 
     return false; 
    } 
    $_SESSION = []; 
    setcookie(
     $this->name, 
     '', 
     time() - 42000, 
     $this->cookie['path'], 
     $this->cookie['domain'], 
     $this->cookie['secure'], 
     $this->cookie['httponly'] 
    ); 
    return session_destroy(); 
} 

public function refresh() 
{ 
    return session_regenerate_id(false); 
} 

public function write($id, $data) 
{ 
    $data = encrypt($data, $this->key); 
    return parent::write($id, $data); 

} 

public function read($id) 
{ 
    $data = parent::read($id); 

    if (!$data) { 
     return ""; 
    } else { 
     return decrypt($data, $this->key); 
    } 
} 

public function isExpired($ttl = 30) 
{ 
    $last = isset($_SESSION['_last_activity']) 
     ? $_SESSION['_last_activity'] 
     : false; 
    if ($last !== false && time() - $last > $ttl * 60) { 
     return true; 
    } 
    $_SESSION['_last_activity'] = time(); 
    return false; 
} 

public function isFingerprint() 
{ 
    $hash = md5(
     $_SERVER['HTTP_USER_AGENT'] . 
     (ip2long($_SERVER['REMOTE_ADDR']) & ip2long('255.255.0.0')) 
    ); 
    if (isset($_SESSION['_fingerprint'])) { 
     return $_SESSION['_fingerprint'] === $hash; 
    } 
    $_SESSION['_fingerprint'] = $hash; 
    return true; 
} 

public function isValid() 
{ 
    return ! $this->isExpired() && $this->isFingerprint(); 
} 
public function get($name) 
{ 
    $parsed = explode('.', $name); 
    $result = $_SESSION; 
    while ($parsed) { 
     $next = array_shift($parsed); 
     if (isset($result[$next])) { 
      $result = $result[$next]; 
     } else { 
      return null; 
     } 
    } 
    return $result; 
} 
public function put($name, $value) 
{ 
    $parsed = explode('.', $name); 
    $session =& $_SESSION; 
    while (count($parsed) > 1) { 
     $next = array_shift($parsed); 
     if (! isset($session[$next]) || ! is_array($session[$next])) { 
      $session[$next] = []; 
     } 
     $session =& $session[$next]; 
    } 
    $session[array_shift($parsed)] = $value; 
    } 
    } 

    $key = file_get_contents('./key.pem', FILE_USE_INCLUDE_PATH); 
    $session = new SecureSessionHandler($key); 

    ini_set('session.save_handler', 'files'); 
    session_set_save_handler($session, true); 
    session_save_path(__DIR__ . '/sessions'); 

    $session->start('cheese'); 
    if (! $session->isValid(5)) { 
    $session->destroy('cheese'); 
    } 

は、すべてが全体的に正常に動作し、完全なセッションハンドラおよび暗号化/復号化方式があるが、問題がある:

すべては、いくつかのコンテキストのためのセッション処理コードは以下の通りです、カスタムセッションハンドラなしで正常に動作しますショッピングカートのコードを見て、すべての$ _SESSION変数を$ session-> getオブジェクトに変更すると、$ _SESSIONごとに置き換えられました。最後に変更する必要があるのは致命的なエラーです:

"$ _SESSION ['cart_contents'] = $ this-> cart_contents; " から "$ session-> get( 'cart_contents')= $ this-> cart_contents;"中

結果:

致命的なエラー:Cに書き込みコンテキストでメソッドの戻り値を使用することはできません:\ xamppの\ htdocsに\ TECKライン375

重要なコードの残りの部分を上Cart.php \私は何も残されていないことを確かめました。すべての細部を欠いている小さなポストのために炎上するよりも細部まで長いポストを持つ方が良いです。

あなたが上の量を調整することができ、ページがviewcart.phpで、コードは、このページから重要なthatsの下にある:

<input type="number" class="form-control text-center" value="<?php echo 
$item["qty"]; ?>" onchange="updateCartItem(this, '<?php echo 
$item["rowid"]; ?>')"> 

とスロー同じページ(viewcart.php)上のスクリプトアラートは以下の通りです:

<script> 
    function updateCartItem(obj,id){ 
    $.get("cartAction.php", {action:"updateCartItem", id:id, qty:obj.value}, 
    function(data){ 
     if(data == 'ok'){ 
      location.reload(); 
     }else{ 
      alert('Cart update failed, please try again.'); 
     } 
    }); 
} 
</script> 

ついにアクションのコードは "updatecartitem" は、以下である、cartaction.php:

}elseif($_REQUEST['action'] == 'updateCartItem' && !empty($_REQUEST['id'])) 
{ 
    $itemData = array(
     'rowid' => $_REQUEST['id'], 
     'qty' => $_REQUEST['qty'] 
    ); 
    $updateItem = $cart->update($itemData); 
    echo $updateItem?'ok':'err';die; 

} 
cart.phpでの

更新機能のthats:

public function update($item = array()){ 
    if (!is_array($item) OR count($item) === 0){ 
     return FALSE; 
    }else{ 
     if (!isset($item['rowid'], $this->cart_contents[$item['rowid']])){ 
      return FALSE; 
     }else{ 
      // prep the quantity 
      if(isset($item['qty'])){ 
       $item['qty'] = filter_var($item['qty'], 
     FILTER_VALIDATE_INT); 
       // remove the item from the cart, if quantity is zero 
       if ($item['qty'] == 0){ 
        unset($this->cart_contents[$item['rowid']]); 
        return TRUE; 
       } 
      } 

      // find updatable keys 
      $keys = array_intersect(array_keys($this- 
     >cart_contents[$item['rowid']]), array_keys($item)); 
      // prep the price 
      if(isset($item['price'])){ 
       $item['price'] = filter_var($item['price'], 
    FILTER_VALIDATE_FLOAT); 
      } 
      // product id & name shouldn't be changed 
      foreach(array_diff($keys, array('id', 'name')) as $key){ 
       $this->cart_contents[$item['rowid']][$key] = $item[$key]; 
      } 
      // save cart data 
      $this->save_cart(); 


      return TRUE; 
     } 
    } 
    } 

そして最後にではなく、少なくとももcart.phpでsave_cart機能:

protected function save_cart(){ 
    $this->cart_contents['total_items'] = $this->cart_contents['cart_total'] 
    = 0; 
    foreach ($this->cart_contents as $key => $val){ 
     // make sure the array contains the proper indexes 
     if(!is_array($val) OR !isset($val['price'], $val['qty'])){ 
      continue; 
     } 

     $this->cart_contents['cart_total'] += ($val['price'] * $val['qty']); 
     $this->cart_contents['total_items'] += $val['qty']; 
     $this->cart_contents[$key]['subtotal'] = ($this->cart_contents[$key] 
     ['price'] * $this->cart_contents[$key]['qty']); 
    } 
    global $key; 
    global $session; 

    // if cart empty, delete it from the session 
    if(count($this->cart_contents) <= 2){ 
     $session->forget(); 
     return FALSE; 
    }else{ 



     // original code below 
    $_SESSION['cart_contents'] = $this->cart_contents; 





     // code below is what i think will clear everything up but throws the 
     // error. 
     $session->get('cart_contents') = $this->cart_contents; 
     return TRUE; 




    } 
    } 

カートのコードは、上記と同じファイルでありますセッションハンドラ

「$ _SESSION ['cart_contents'] = $ this-> cart_contents;」という説明をもう少し詳しく説明します。

ボタンを押してカートに余分なアイテムを追加すると、テキストフィールドが1増加し、「カートの更新に失敗しました。もう一度やり直してください」というエラーアラートが表示されます。アラートが消えて何も起こらない場合、テキストボックス内のアイテムの数量は更新されたままになりますが、ページを更新するかリンクをクリックするまで、実際のカートの数量は更新されません。

標準のセッションハンドラを使用すると、これは起こりません。すべてが完全に機能します。

この$ _SESSION ['cart_contents']変数を$ session-> get( 'cart_contents')に変更する必要がありますか?

アラートを投げずにカートを適切に更新するためにスクリプトアラートを変更することはできますが、そのセッション変数を残しても私のカスタムセッションハンドラは完璧に機能しますか?

非常に残念ですが、他の人が同様の問題を抱えているかどうかについては、できる限り明確にしています。

コードはこの観点からはかなり乱雑に思えますが、サイト全体を見渡すと、すべて意味があります。

私は最大2ヶ月間phpを使い続けていますので、できるだけ多くのものを手に入れようとしていますので、私と同行してください。明らかに、コードの大部分はきれいではありません。

私はこのセッションハンドラで過去3〜4日を費やしましたが、私は本当にそれを急にして標準の_セッションに戻ってはいけません。

すべて&助言を歓迎します、建設的な批判は軽く取られます!

本当にありがとうございました。これを通過する時間がありました。ありがとうございます!

+1

ある人は自分の質問を説明していないし、その人がいる – rak007

答えて

0

あなたは

$session->get('cart_contents') = $this->cart_contents; 

ライン

でエラーを取得しているここで私は、get関数が参照を返すと仮定します。ですから$ this-> cart_contentsを参照変数に格納する場合は$$を使用する必要があります。 例:$ temp = $ session-> get( 'cart_contents'); と$$ temp = $ this-> cart_contentsを使用してください。

それともます$ this-を割り当てる場合>カートの値にcart_contentsその後、あなたはあなただけのgetメソッドを使用して、それに値を割り当てるカント

$this->cart_contents = $session->get('cart_contents'); 

を使用する必要があります。

+0

私はすでに "$ this-> cart_contents = $ session-> get( 'cart_contents');"を試しています。 $$ SITSION ['cart_contents'] = $ this-> cart_contents; "、$$多分それを間違って実装しています。ありがとう、ありがとうあなたの入力のために。 –

+0

私はgetメソッドを使用する必要がありますか?私のセッションハンドラから "$ _SESSION ['cart_contents']"を置き換えるのに何を使うべきですか? getは、 "$ _SESSION ['cart_contents']"という印字のようなカートの詳細の配列を返しますので、それを置き換えるには問題ないと思います。 –

+0

$セッションクラスの関数を設定したファイルで、setメソッドをチェックします。次に、セッションで変数を設定する方法についてのアイデアを得ることができます。 –

0

リサーチを続けることとは別に、実際にそれを動作させるために何が行われたのかは分かりませんが、私のカスタムセッションハンドラが意図した通りに動作しなくなるのであれば教えてください。

私はupdateCartItem関数が変更されていないので、if文はまっすぐに関数を呼び出してからページをリロードします。

<script> 
function updateCartItem(obj,id){ 
$.get("cartAction.php", {action:"updateCartItem", id:id, qty:obj.value}, 
function(data){ 
     location.reload(); 
}); 
}</script> 

これは以下のようにsave_cart機能を正常に動作します:

protected function save_cart(){ 
$this->cart_contents['total_items'] = $this->cart_contents['cart_total'] 
= 0; 
foreach ($this->cart_contents as $key => $val){ 
    // make sure the array contains the proper indexes 
    if(!is_array($val) OR !isset($val['price'], $val['qty'])){ 
     continue; 
    } 

    $this->cart_contents['cart_total'] += ($val['price'] * $val['qty']); 
    $this->cart_contents['total_items'] += $val['qty']; 
    $this->cart_contents[$key]['subtotal'] = ($this->cart_contents[$key] 
    ['price'] * $this->cart_contents[$key]['qty']); 
} 
global $key; 
global $session; 

// if cart empty, delete it from the session 
if(count($this->cart_contents) <= 2){ 
    $session->forget(); 
    return FALSE; 
}else{ 
$_SESSION['cart_contents'] = $this->cart_contents; 
    return TRUE; 
} 
} 

しかし! $ _SESSION変数を私のカスタムセッションハンドラ呼び出しで置き換えることはできませんか? ($ session-> get( 'cart_contents')= $ this-> cart_contents;)私がそれを変更した場合、明らかにエラーが出る:(

セッションですべてうまくいくように見えますが、そして私はupdateCartItemスクリプトでifステートメントを使用できるはずです! "$ _SESSION ['cart_contents']"の代わりにcustomsessionhandler呼び出しを使用する方法が必要です。

関連する問題