在 PHP 中,URL 中的 "?" 符号用于什么?

10

我刚开始学习PHP。在学习PHP语言的过程中,我注意到一些网站会使用这种URL:

www.website.com/profile.php?user=roa3&...

我的问题:

  1. "?"符号用于什么目的?

  2. 如果我要开发一个PHP网站,必须在我的URL中使用它吗?例如,当用户(roa3)成功登录后,我将重定向到“www.website.com/profile.php?user=roa3”,而不是“www.website.com/profile.php”。

  3. 使用它有哪些优缺点?

7个回答

23

简而言之,好问题:

  1. "?"代表查询字符串(query string)的起点,包含要传递给服务器的数据。在这种情况下,您正在向profile.php页面传递user=roa3。您可以通过在profile.php中使用$_GET['user']来获取数据。查询字符串是将数据从客户端代理发送到服务器的方法之一。另一个方法是将数据放入HTTP正文并POST到服务器,您无法直接从浏览器查看HTTP POST数据。

  2. 查询字符串可以被用户编辑,并且对公众可见。如果www.website.com/profile.php?user=roa3旨在成为公开的,则可以使用会话(session)来获取当前用户的上下文信息。

  3. 它是将数据传递给服务器的一种灵活方式,但用户可以看到和编辑该数据。对于某些敏感数据,至少在将其附加到查询字符串之前生成某种哈希值,以防止用户编辑或理解其含义。但是,这不能阻止一个优秀的黑客对你的网站做出错误操作。不同的浏览器支持不同的URL最大长度,长度较长的URL由这些查询字符串参数组成。如果要发送大量数据,请将数据放入HTTP正文并POST到服务器。


6
迄今为止,我看到的大多数答案都是关于PHP的,但实际上这并不特定于语言。到目前为止给出的答案是从PHP的角度出发的,而访问信息所使用的方法因语言而异,但数据在URL中的格式(称为查询字符串)将保持不变(例如:page.ext?key1=value&key2=value&...)。
我不知道您的技术背景或知识,所以请原谅我...
网页向Web服务器提供数据有两种不同的方法,这些方法被称为POST或GET方法。还有其他一些方法,但在处理普通用户时不应使用这些方法中的任何一种。POST方法被发送到服务器,对用户不可见,用于“上传”数据,而GET方法作为URL中的查询字符串对用户可见,仅用于“获取”信息。
并非所有站点都遵循这个经验法则,但可能有其原因。例如,一个站点可以专门使用POST来绕过代理服务器或浏览器的缓存,或者因为他们使用双字节语言,在尝试执行GET时可能会由于编码转换而出现问题。
一些关于这两种方法以及何时使用它们的资源...

http://www.cs.tut.fi/~jkorpela/forms/methods.html http://weblogs.asp.net/mschwarz/archive/2006/12/04/post-vs-get.aspx http://en.wikipedia.org/wiki/Query_string

从纯粹的PHP角度来看,现在有三种不同的数组可以用来获取网页发送回服务器的信息。您可以使用以下内容:

  • $_POST ['keyname'],仅从POST方法中获取信息
  • $_GET ['keyname'],仅从GET方法中获取信息
  • $_REQUEST ['keyname'],允许您获取已提交的POST、GET和任何COOKIE信息。在某些情况下,这是一个万能方法,特别是当您不知道页面可能使用哪种方法提交数据时。

不要直接使用$_REQUEST方法。除非您像上面提到的那样有一个$_REQUEST变量的情况,否则不要使用它。在安全性方面,您想尝试使用“拒绝所有,只允许x,y,z”的方法。仅查找您知道自己网站将发送的数据,仅查找您期望的组合,并在使用之前清理所有信息。例如...

  • 不要对通过上述方法传递的任何内容执行eval()操作。我从未见过这样做,但这并不意味着人们没有尝试或执行。
  • 不要直接将信息用于数据库而不进行清理(如果您不熟悉SQL注入攻击,请研究一下)

这远非PHP安全的全部,但我们不在这里讨论这个。如果您想了解更多相关内容,请另外提问。

希望这有所帮助,如有任何问题,请随时提问。


4

1) 如果用户登录您的网站,您应使用Sessions存储他们的用户名,而不是通过url传递它,例如profile.php?username=roa3

2) 在网址中使用?符号通常被认为对于搜索引擎优化不利。此外,网址看起来有点丑陋。使用mod_rewrite,您可以使用以下方式完成与profile.php?user=roa3products.php?id=123&category=toys相同的事情:site.com/profile/roa3products/toys/123

使用CodeIgniter框架默认提供友好的URL,并消除了在网址中使用?的需要。请参阅此页面以获取示例。

3) ?符号也用于php页面的代码中。例如,一个if else语句块如下:

if ($x==1)
   $y=2;
else
   $y=3;

还可以写成:

$y=($x==1) ? 2 : 3;

3
"?"符号表示接下来会有一些GET变量。你的例子使用了一个名为"user"的变量,并将一个名为"roa3"的变量赋值给它。
使用GET变量的优点: - 它们可以作为URL的一部分被书签保存。
缺点: - 它们是公开的。任何人都可以截取并查看这些信息。这些URL请求甚至会被沿途的服务器缓存。因此,任何人都可以通过手动输入该信息来冒充你的roa3用户... 他们还可以将roa3更改为其他用户并冒充他们...
你也可以使用"&"符号来分隔多个变量,例如: www.website.com/profile.php?user=roa3&fav_colour=blue 其他选项: - POST变量: - 您可以通过POST变量发送您的变量。这些变量在请求的头中传递,而不是在请求的URL中传递。它们不是立即显而易见的,并且不会被沿途的服务器缓存,但它们仍然可以被读取,除非您已经建立了HTTPS连接。 - 表单中的变量可以通过POST或GET方法发送。您可以在表单的"method"中指定这一点。例如:<form action="index.php" method='post'/> - SESSION变量: - 会话变量存储在服务器上。会话ID被传递给用户,每当用户发出另一个请求时,该会话ID就会被传回服务器。然后可以使用此会话ID来获取存储的会话变量。因此,您可以存储用户的最喜欢颜色、姓名和IP地址等信息,但可以将其存储在服务器而不是用户的家用电脑上。 - 会话ID可以被冒充,因此最好检查用户的IP,并/或将它们包装在安全连接中,例如HTTPS。 - 会话变量无法被截取请求的人更改。 - COOKIE变量: - 与会话变量类似,只是它们存储在用户的PC上,而不是服务器上。它们存储在域名下,当他们访问该域名时,它们会在请求的头中重新提交变量。这意味着用户可以更改和黑客变量,或其他人也可以。
要在php中访问这些变量,您可以使用: - 对于GET变量:$x = $_GET['user'] - 对于POST变量:$x = $_POST['user] - 对于组合了GET、POST和COOKIE变量的REQUEST变量:$x = $_REQUEST['user'] - 对于COOKIE变量:$x = $_COOKIE['user'] - 对于SESSION变量:$x = $_SESSION['user']"

user可以替换为您使用的变量名称)

这些都是非常简单的内容,但了解它们的实际作用非常重要。


1
如果人们坐在具有多个IP地址的代理服务器群后面,检查会话ID与IP的匹配并不是很好。此外,共享一个代理的人仍然无法从另一个代理中获得保护。如果您处理敏感数据,则应用程序必须以另一种方式处理此问题 - 使用https。 - Olaf Kock
是的,这是真的。检查IP地址与会话相比会增加安全性,但也会留下一些漏洞。在建立HTTPS之后建立会话始终是最安全的。 - Bingy
只是一点小事:在分隔 GET 变量时使用 ';' 是合法的。虽然我从未见过这种用法,因此不建议使用。 - alex

2

问号(?)是HTTP标准的一部分,而不是PHP的一部分。我认为我应该指出这一点,这样当您转到另一种语言并再次看到它时,您不会因为认为涉及PHP而感到困惑。

否则,上面有一些很好的答案。


0

从服务器的角度来看,问号?只是另一个字符。PHP提供了简单的方法来获取问号后面的URL部分,例如对于"/profile.php?user=roa3",PHP将设置$_GET ['user'] ='roa3'。

问号在URL中有用的原因是浏览器可以使用表单构建动态URL - 在上面的例子中,我希望该URL是由HTTP表单构建的,其中包含一个名为“user”的字段,人类用户已经输入了“roa3”。


这是错误的。对于服务器来说,“?” 不是“只是另一个字符”。服务器会在“?”上分割URL(如果存在)。它前面的部分是所请求的文件,后面的部分是“查询字符串”,将其展示给CGI作为QUERY_STRING环境变量。 - nobody
1
我应该明确指出,通常情况下服务器不会特别处理它。在PHP(以及大多数其他Web框架)的情况下,会提供一些处理方式,正如我接下来所讨论的那样。这个问题没有明确指定CGI。 - Edmund
1
它可能对服务器来说并不特别,但它是HTTP标准的一部分,而不是php。 - Toby Allen
我在这里固执地坚持我的立场 :-) RFC21616,S13.9中只有一个有效的?区别:“除非服务器提供显式的过期时间,否则缓存不得将[查询URI]的响应视为新鲜的。” 这似乎并不相关。 - Edmund
1
好的,对于一个基本正确的答案(有一个小小的限制)而遭受四个反对票显然是过度的,将其标记为冒犯更是纯粹...嗯,冒犯! - Konrad Rudolph

0
  1. "?"用于分隔URL和参数。例如,它类似于http://www.url.com/resourcepath?a=b&c=d。在这种情况下,a=b就像请求参数=请求值。

  2. 是的,不建议使用太多参数,因为总URL大小有限,就像GET请求一样,所有参数都显示在URL上,用户可以修改它。在您的示例中,假设用户将URL修改为"user=techmaddy"。

  3. 优点是它可用于GET类型的请求。缺点是安全性低,大小受限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接