PHP - 发送脚本的url-address

I'm creating pagging for some data. For example, I have a page:

http://example.com/news.php?type=bla&smth=bla

There are I have a list of news with links to another pages. Link to the first page is:

http://example.com/news.php?type=bla&smth=bla&page=1

Here is script, which creates pages links:

print '<a href="?'.$_SERVER['QUERY_STRING'].'&page=1"><<</a>'; 

But after clicking to another pages the link URL is very large and it looks like:

http://example.com/news.php?type=bla&smth=bla&page=1&page=2&page=1&page=3

How can I change that?

You are just append the new paremeter to the old ones but you don’t replace it if already existing. So you rather need to merge the old query string with the new one:

// either by merging both arrays
$query = array_merge($_GET, array('page'=>1));
// or by the union of both
$query = array('page'=>1) + $_GET;
// or by altering the array
$query = $_GET;
$query['page'] = 1;

And PHP does already have a http_build_str that can build you a query string from an associative array:

print '<a href="?' . htmlspecialchars(http_build_str($query)) . '">&lt;&lt;</a>';

Edit    Here’s an alternative definition of http_build_str:

if (!function_exists('http_build_str')) {
    function http_build_str($query, $prefix='', $arg_separator='') {
        if (!is_array($query)) {
            return null;
        }
        if ($arg_separator == '') {
            $arg_separator = ini_get('arg_separator.output');
        }
        $args = array();
        foreach ($query as $key => $val) {
            $name = $prefix.$key;
            if (!is_numeric($name)) {
                $args[] = rawurlencode($name).'='.urlencode($val);
            }
        }
        return implode($arg_separator, $args);
    }
}

Every time you run that script a page parameter will be appended to the query string. For instance when you get to page one the query string will be:

http://site.com/news.php?type=bla&smth=bla

and when you get to page to the query string will be

http://site.com/news.php?type=bla&smth=bla&page=1

and so on for everyone page that you go to.

I would suggest instead writing a function that takes parameters from an array and formats them as a query string and then change them as needed.

So something along the lines of:

<?php

$parameters = array(
  'type' => 'bla',
  'smth' => 'bla',
  'page' => 1,  // Of course, logic up front to change the value of this
);

print print '<a href="?' . format_url_parameters($parameters) .'>Link</a>';

// format_url_parameters producing a valid query string here

You could also simply use

print '<a href="http://'. $_SERVER["HTTP_HOST"] . $_SERVER['REQUEST_URI'].'?page=1"><<</a>';

this generates an absolute URL each time.

The simplest is to do the following:

$params = $_GET;     // make a copy of the querystring params
$params['page'] = 1; // will replace any existing 'page' parameter
echo '<a href="?'.http_build_query($params)'">Page 1</a>';

The alternative http_build_str does not handle inner arrays, therefor, i suggest the following:

function http_build_str_inner($query, $prefix, $arg_separator,&$args) {
    if (!is_array($query)) {
        return null;
    }
    foreach ($query as $key => $val) {
        $name = $prefix."[".$key."]";
        if (!is_numeric($name)) {
            if(is_array($val)){
                http_build_str_inner($val,$name,$arg_separator,$args);
            }else{
                $args[] = rawurlencode($name).'='.urlencode($val);
            }
        }
    }   
}

function http_build_str($query, $prefix='', $arg_separator='') {
    if (!is_array($query)) {
        return null;
    }
    if ($arg_separator == '') {
        $arg_separator = ini_get('arg_separator.output');
    }
    $args = array();
    foreach ($query as $key => $val) {
        $name = $prefix.$key;
        if (!is_numeric($name)) {
            if(is_array($val)){
                http_build_str_inner($val,$name,$arg_separator,$args);
            }else{
                $args[] = rawurlencode($name).'='.urlencode($val);
            }
        }
    }
    return implode($arg_separator, $args);
}

Enjoy...