使用友好URL更改.htaccess时无法获取变量

I'm an amateur in php. I have a website where I load projects from a DB and for example when I want to load a proyect the url is like this

www.mywesite.com/proyecto.php?id=1

I did a .htaccess to use this url:

www.mywebsite.com/proyecto/id/1

.htaccess

<ifModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine on
  RewriteRule proyecto/id/(.*)/ proyecto.php?id=$1 
  RewriteRule proyecto/id/(.*) proyecto.php?id=$1 
  RewriteRule ^([^\.]+)$ $1.php [NC,L]
  ErrorDocument 404 /error404.php
</ifModule>

The problem now is that the variables are undefined because of the change of the url I think. This is how I get the variables

$valorid = $_GET['id'];
$connection = new 
PDO('mysql:host='.$host.';dbname='.$db_name.';charset=utf8',''.$username.'', ''.$password.'');
foreach($connection->query('SELECT * FROM grafica WHERE id = '.$valorid.'') 
as $row) {

}

And I set the like this

<?php echo $row['nombre'] />

Hope anyone can help with this.

Thanks in advanced.

In regards to your question, this was already answered here: URL rewriting with PHP

In the future, please make sure to search for possible solutions. Consider the following in your .htaccess file:

<ifModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine on
  RewriteRule ^/proyecto/id/([0-9]+)/$ /proyecto.php?id=$1 
  RewriteRule ^([^\.]+)$ $1.php [NC,L]
  ErrorDocument 404 /error404.php
</ifModule>

This is the first step to creating a more secure GET Request. For example, this will pass:

www.mywebsite.com/proyecto/id/1/

While a malicious attempt should fail:

www.mywebsite.com/proyecto/id/%5Cxbf%5Cx27%20OR%201%3D1%20%2F*

This would pass \xbf\x27 OR 1=1 /* to your script and could be potentially harmful payload. Since this value is not 0 through 9, the rewrite condition should not be met.

On to your SQL Query. This is the next level of defense, we want to ensure that we only use an integer variable type. To do this, we want to sanitize the input from the browser in some way. More than one way to do this. We can do it before passing the variable to the query or we can use PDO Functions.

Example 1: Santize the variable before Query

Instead of using:

$valorid = $_GET['id'];

Where whatever is entered as id will be placed in the variable, we can force it to be a number. Something like:

$valorid = sprintf("%d", $_GET['id']);

This is a less used method, since it's basically formatting the variable into a digit.

Example 2: Using PDO Prepared Statement

Refer to: http://php.net/manual/en/pdo.prepared-statements.php

Consider the following:

$conn = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8",$username, $password);
$stmt = $conn->prepare('SELECT * FROM grafica WHERE id = ? LIMIT 1');
if ($stmt->execute(array($_GET['id']))) {
  while ($row = $stmt->fetch()) {
    // Do the needful
  }
}

This is considered a better method. One, we have improved the statement with LIMIT 1 to ensure we only get 1 result. Two, PDO will prepare the statement and ensure that all potentially harmful elements are handled, commented, or obscured.

Prepares an SQL statement to be executed by the PDOStatement::execute() method. The SQL statement can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed. You cannot use both named and question mark parameter markers within the same SQL statement; pick one or the other parameter style. Use these parameters to bind any user-input, do not include the user-input directly in the query.

Hope that helps.