【问题标题】:Warning: urlencode() expects parameter 1 to be string, array given in ... on line警告:urlencode() 期望参数 1 是字符串,数组在 ... 在线
【发布时间】:2021-06-20 21:46:31
【问题描述】:

我是一名初级程序员。仅在 php.ini 中。 在 php 上,我处于程序风格。还没有在 oop 或 pdo 上。因此,您会看到 mysqli 和程序样式。

我正在构建一个带有分页的 SERP。就像谷歌一样,当他们向您显示您的关键字搜索结果时。

不要误会我的主题。没有试图阻止 Sql 注入,因为我设法使用准备好的语句来做到这一点。 学习使用urlencode()rawurlencode()htmlentities(),因为我正在尝试使用它们来防止用户注入不需要的 html 标签来破坏我的 SERP 的 html。

在这种情况下,我在正确使用 urlencode() 时遇到问题。 我收到此错误:

警告:urlencode() 期望参数 1 是字符串,数组在 ... 在线 ...

以下是相关行,因为我 urlencode() 他们的值,所以没有用户(关键字搜索者)可以注入 html 标签来分解我的 SERP 的 html:

$search = $_GET['search']; //Keyword(s) to search.
$col = $_GET['col']; //MySql Tbl Col to search.
$tbl = $_GET['tbl']; //MySql Tbl to search.
$max = $_GET['max']; //Max Result per page.
$page = $_GET['page']; //Serp Number.

上述变量每个都包含一个值,因为每个 $_GET 每个都包含一个值,即使 $_GET 是一个全局变量(数组)。所以在这里,与数组无关或每个变量有多个值。

问题出现在 WHILE 循环之后的以下行: 第 145 行

$query_string_1 = '?search=' .urlencode($search) .'&tbl=' .urlencode($tbl) .'&col=' .urlencode($col) .'&max=' .intval($max);

这里是代码上下文:

//ERROR REPORTING FOR DEVMODE ONLY.
ini_set('display_errors','1');
ini_set('display_startup_errors','1');
error_reporting(E_ALL);


//MYSQLI CONNECTION.
mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);

$server = 'localhost';
$user = 'root';
$password = '';
$database = 'brute';

if(!$conn = mysqli_connect("$server","$user","$password","$database"))
{
    echo 'Mysqli Connection Error' .mysqli_connect_error($conn);
    echo 'Mysqli Connection Error Number' .mysqli_connect_errno($conn);
}

if(!mysqli_character_set_name($conn) == 'utf8mb4')
{
    echo 'Initial Character Set: ' .mysqli_character_set_name($conn);
    mysqli_set_charset("$conn",'utf8mb4');
    echo 'Current Character Set: ' .mysqli_character_set_name($conn);
}


//PAGINATION SECTION.
$search = $_GET['search']; //Keyword(s) to search.
$col = $_GET['col']; //MySql Tbl Col to search.
$tbl = $_GET['tbl']; //MySql Tbl to search.
$max = $_GET['max']; //Max Result per page.
$page = $_GET['page']; //Serp Number.


//QUERY DATABASE FOR KEYWORD COUNT.
$query = "SELECT COUNT(id) From links WHERE keyword = ?";
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
    mysqli_stmt_bind_param($stmt,'s',$search);
    mysqli_stmt_execute($stmt);
    mysqli_stmt_bind_result($stmt,$row_count);
    if(mysqli_stmt_fetch($stmt))
    {
        echo 'Row Count: ' .$row_count; echo '<br>';    
    }
    else
    {
        echo 'Record fetching failed!';
        echo 'Error: ' .mysqli_stmt_error($conn);
        echo 'Error: ' .mysqli_stmt_errno($conn);
    }
    mysqli_stmt_close($stmt);
}
else
{
    echo 'Search Preparation Failed!';
}
//mysqli_close($conn);
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';


//START KEYWORD SEARCH & OUTPUT RESULT
echo $offset = ($page*$max)-$max; echo '<br>';
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';
$query = "SELECT id,date_and_time,domain,domain_email,ip,url,anchor,title,description,keyword,keyphrase From links WHERE keyword = ? LIMIT $offset,$max";
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
    mysqli_stmt_bind_param($stmt,'s',$search);
    mysqli_stmt_execute($stmt);
    if($result = mysqli_stmt_get_result($stmt))
    {
        /*
        FOLLOWING BOTH ARE EQUAL:
        $col = mysqli_fetch_array($result) //SHORT VERSION.
        $col = mysqli_fetch_array($result,MYSQLI_BOTH) //LONG VERSION.
        */
        $col = mysqli_fetch_array($result); //SHORT VERSION.
        
        $id = $col['0']; //MYSQLI_NUM
        $date_and_time = $col['date_and_time']; //MYSQLI_ASSOC
        $domain = $col['2']; //MYSQLI_NUM
        $domain_email = $col['domain_email']; //MYSQLI_ASSOC
        $ip = $col['4']; //MYSQLI_NUM
        $url = $col['url']; //MYSQLI_ASSOC
        $anchor = $col['6']; //MYSQLI_NUM
        $title = $col['title']; //MYSQLI_ASSOC
        $description = $col['8']; //MYSQLI_NUM
        $keyword = $col['keyword']; //MYSQLI_ASSOC
        $keyphrase = $col['10']; //MYSQLI_NUM

        echo 'Id: ' .$id; echo '<br>';
        echo 'Date And Time: ' .$date_and_time; echo '<br>';
        echo 'Domain: ' .$domain; echo '<br>';
        echo 'Domain Email: ' .$domain_email; echo '<br>';
        echo 'Ip: ' .$ip; echo '<br>';
        echo 'Url: ' .$url; echo '<br>';
        echo 'Anchor: ' .$anchor; echo '<br>';
        echo 'Title: ' .$title; echo '<br>';
        echo 'Description: ' .$description; echo '<br>';
        echo 'Keyword: ' .$keyword; echo '<br>';
        echo 'Keyphrase: ' .$keyphrase; echo '<br>';        
    }
    else
    {
        echo 'Record fetching failed!';
        echo 'Error: ' .mysqli_stmt_error($stmt);
        echo 'Error: ' .mysqli_stmt_errno($stmt);
    }
    mysqli_stmt_close($stmt);
}
mysqli_close($conn);
echo '<b>'; echo __LINE__; echo '</b>'; echo '<br>';


//PAGINATION SECTION TO NUMBER THE PAGES AND LINK THEM.
$total_pages = ceil($row_count/$max);
$i = '1'; 

//$selfpage = $_SERVER['PHP_SELF'];
$selfpage = basename(__FILE__,''); //Echoes: url_encode_Template.php. Does not fetch the url $_GET params.
$path = rawurlencode($selfpage);
$query_string_1 = '?search=' .urlencode($search) .'&tbl=' .urlencode($tbl) .'&col=' .urlencode($col) .'&max=' .intval($max);

while($i<=$total_pages)
{
    $query_string_2 = '&page=' .intval($i);
    $url = $path .htmlentities($query_string_1) .htmlentities($query_string_2); //Full URL With $_GET params: https://localhost/Templates/url_encode_Template.php?search=keyword&tbl=links&col=keyword&max=100&page=1

    if($page == $i)
    {
        echo '<a href=' .'"' .$url .'"' .'>' .'<b>' .intval($i) .'</b>' .'</a>';
    }
    else
    {
        echo '<a href=' .'"' .$url .'"' .'>' .intval($i) .'</a>';
    }
    $i++;
}
?>

坦率地说,分页页面快完成了,如果不是这个urlencode() 问题! 如果您发现由于忽略它们而导致我没有询问的任何其他错误,请通过编辑我的代码向我展示代码示例,以便向我展示我应该如何编写它。 (我说的是我对urlencode()rawurlencode()htmlentities() 的使用,因为我试图使用它们来防止用户注入不需要的 html 标签)来破坏我的 SERP。

如果我的代码由某人编辑并且更正显示在此线程上,无论我哪里出错,我将不胜感激。

【问题讨论】:

  • 你确定你的输入都没有名称作为数组,例如。 name='search[]' ..... 因为你的一个或一些 GET 值是数组
  • 如果要防止XSS(HTML或JavaScript的注入),可以使用strip_tags()
  • @ket-c,是的,$search 不是一个数组。 $_GET['search'] 从 url 获取字符串值。网址是:localhost/Templates/….
  • @ket-c,问题已解决。我有两个名为 equal 的不同变量。就像 Rob Ructhe 指出的那样。

标签: php html urlencode


【解决方案1】:

您的问题是您正在用关键字搜索的结果覆盖您最初在 GET 请求中使用“col”参数填充的 $col 变量的值。

$col = $_GET['col']; //MySql Tbl Col to search.
...
$col = mysqli_fetch_array($result); //SHORT VERSION.

您似乎没有将col 参数用于任何事情,您可以将其从查询字符串中删除。如果您确实打算使用它,只需将您用于查询结果行的变量重命名即可。

为了将来参考,您可以使用http_build_query 函数将数组值编码为查询字符串。这将简化您的代码,并且可以让您看到问题是否在这种情况下。

// Set some test values for the parameters
$search = 'my search term';
$tbl = 'my_table_name';
$col = 'column_1';
$max = 10;

// Simulate variable being overwritten with database result
$col = [
    'id' => 123,
    'date_and_time' => '2021-06-20 09:44:00',
    'domain' => 'stackoverflow.com'
];

// Build an array of the parameters to be included in the query string
$queryParameters = [
    'search' => $search,
    'tbl' => $tbl,
    'col' => $col,
    'max' => $max
];

/*
 * Build the query string using http_build_query
 * Any array values will be represented appropriately
 * Prepend the ? to the result
 */
$query_string_1 = '?'.http_build_query($queryParameters);

echo $query_string_1.PHP_EOL;

【讨论】:

  • 感谢您的反馈。你是对的,我将 2 个变量命名为相同的。我现在将第二个重命名为 $cols。错误消失了。
猜你喜欢
  • 1970-01-01
  • 2019-06-21
  • 2016-11-26
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多