PHP - $ _SESSION数组中找不到现有字符串值

时间:2013-02-28 03:16:39

标签: php mysql

之前我问过这个问题,但是没有回复,所以我删除了最后一个问题,并简化/澄清了问题,并重新发布


我有一个漫画网站......我正在研究一种SO风格的标记系统。用户可以选择1个或多个标签,这些标签将显示所有相关的漫画。

要记住用户选择,我将它们存储在$ _SESSION数组中。

我遇到的问题是用户选择后存储在$ _SESSION ['tagnames']数组中的其中一个字符串'business'未找到在阵列......

它应该工作的方式是用户选择一个标签,并取消选择它们,然后再次点击它...所以我检查字符串是否在$ _SESSION中...如果是,则取消设置..这是一个片段:

    //var_dump shows these are both set fine when a user clicks on the tag they want
    $tagid = (isset($_GET['tagid']) ? ($_GET['tagid']) : null); 
    $tagname = (isset($_GET['tagname']) ? ($_GET['tagname']) : null); 

    ...

//Tag IDS are added and removed without issue:
    //if tag id exists in $_SESSION['tags'] array, remove it 

    if ($key = array_search($tagid, $_SESSION['tagids'])) {
        unset($_SESSION['tagids'][$key]);
    }
    else {
        $_SESSION['tagids'][] = $tagid;
    }

    ...

//but one of the tag names, 'business', is not being removed... and is actually added again even when I press F5 to refresh

    if ($key =  array_search($tagname, $_SESSION['tagname'])) {
        unset($_SESSION['tagname'][$key]);
    }
    else {
        $_SESSION['tagname'][] = $tagname;
    }

这是sql语句的var_dump:它正确显示了根据选择的标记ID更改的查询。

enter image description here

以下是var_dump的{​​{1}} ...您可以看到它识别出标签2和3(差异和相似之处)何时已添加(我使用$_SESSION['tagname']检查),但它没有找到tagid 1,'business',尽管它已被多次添加。

enter image description here

以下是将所选标签名称返回给用户的功能:

array_search()

为什么标记'业务'是造成问题的唯一原因?

即使在我销毁会话后,按F5刷新也会自动将标记名'business'放入function getSelectedTags() { global $tagid, $tagname; if ($key = array_search($tagname, $_SESSION['tagname'])) { unset($_SESSION['tagname'][$key]); } else { $_SESSION['tagname'][] = $tagname; } var_dump($_SESSION['tagname']); foreach ($_SESSION['tagname'] as $tagname) { echo '<span class="tags">' . $tagname . '</span>'; } }


编辑:更全面的代码:

Homepage.php:用户点击getDBTags()返回的代码,将标签添加到imageDisplay.php上的$ _SESSION数组

$_SESSION['tagname'] array.

imageDisplay.php:负责处理图片的过滤和显示方式......

getDBTags()返回数据库中的标记选项,以便用户点击它们:

<h5>Tags</h5>
<?php echo getDBTags(); ?>
<br/>
<p>Your tags:</p>
<?php echo getSelectedTags(); ?>

getFilters()决定如何通过动态查询过滤图像,然后将查询发送到pagination(),在页面上显示过滤后的图像。

function getDBTags() {
include 'dbconnect.php';

global $cat;

$sql = "SELECT tagid, tagname FROM tags";

$query = $mysqli->query($sql);

while ($row = $query->fetch_assoc()) {
    echo '<span class="tags"><a href=".?action=homepage&cat='.$cat.'&tagid='.$row['tagid'].'&tagname='.$row['tagname'].'">'.$row['tagname'].'</a></span>';
}
mysqli_close($mysqli);
}

getSelectedTags()将选定的标签标题返回给用户,以便他们可以看到他们选择的内容。如果他们再次点击标签(从上面的 getDBTags()返回),它将从$ _SESSION ['tagname']中删除标签。这是问题所在:

function getFilters() {
include 'dbconnect.php';

global $cat, $site, $table, $tagid;

$order = " ORDER BY date DESC";

//if tag id exists in $_SESSION['tags'] array, remove it 
if ($key = array_search($tagid, $_SESSION['tagids'])) {
    unset($_SESSION['tagids'][$key]);
}
//if it doesn't, add it
else {
    $_SESSION['tagids'][] = $tagid;
}
//var_dump($_SESSION['tagids']);

if ($cat != null) $catquery = " AND catidFK = $cat";
else $catquery = null;

$sql = 
 "SELECT c.*, t.* 
 FROM comics c 
 INNER JOIN comictags ct ON (c.id = ct.comicID)
 INNER JOIN tags t ON (t.tagid = ct.tagID)
 WHERE ct.tagID IN ('" . implode(', ', $_SESSION['tagids']). "')
". $catquery ." " . $order;

if (!$mysqli->query($sql)) printf("<br /><b>Error:</b> %s\n", $mysqli->error); 

$query = $mysqli->query($sql);

var_dump($sql);
mysqli_close($mysqli);

return $query;
}

1 个答案:

答案 0 :(得分:1)

有三个问题突出(两个突出,一个非常微妙)。

1。只打开一个DB连接并保留:

首先,不要在函数的$mysqli中打开和关闭连接,而是在脚本开头执行一次并保持打开状态。您需要修改您的函数以接受$mysqli作为参数(首选)或通过global $mysqli;访问它(不是首选)。无需调用mysqli_close(),因为这是隐式完成的。

getFilters()函数中,您实际上关闭了MySQLi资源$mysqli,然后尝试return $query;其中$query是结果资源。这样做会使结果资源无效。

// Pass $mysqli as a parameter
function getFilters($mysqli) {
  //...
  // Do alll your stuff...
  // And do not call mysqli_close()!
  return $query
}

2。对FALSE使用array_search()

进行严格的比较和测试

使用array_search()时,如果您的结果是键[0]处数组中的第一个元素,那么周围的if ()条件会将其视为错误的返回而非正数结果应该是。因此,位置[0]处的标记将被重复添加而不是被删除。这需要在几个地方修复......

// First get the key, which is an int or FALSE
$key = array_search($tagid, $_SESSION['tagids']);
// Unset if it is FALSE by strict comparison
if ($key !== FALSE) { 
  unset($_SESSION['tagids'][$key]); 
} 
else {
   $_SESSION['tagids'][] = $tagid;
}

3。全局变量$tagnameforeach

破坏

您已访问$tagname中的全局getSelectedTags()。但是在该函数中,你有一个foreach循环,它可以:

foreach ($_SESSION['tagname'] as $tagname)

当使用$tagname作为循环变量时,它实际上会在每次迭代时覆盖全局$tagname。您需要将其更改为其他值,或者当您致电getSelectedTags()时,$tagname全局将成为$_SESSION['tagname']中的最后一个标记,无一例外。

// use a different varname in the loop
foreach ($_SESSION['tagname'] as $tn) {
  // Also calling htmlspecialchars to escape here. Do this in any variable to HTML output...
  echo '<span class="tags">' . htmlspecialchars($tn) . '</span>';
}