仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 965|回复: 19
打印 上一主题 下一主题

[学习教程] PHP网站制作之Coding PHP with register_globals Off...

[复制链接]
精灵巫婆 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-4 00:08:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
用C语言重新编写,包括可以访问数据库。他将这些程序和一些表单直译器整合起来,称为 PHP/FI。PHP/FI 可以和数据库连接,产生简单的动态网页程序。   Intended Audience
Introduction
register_globals
How do the variables get to PHP?

From the URL

From a Form

From a Cookie

From the Environment or the Server
Use the superglobals!

Why are they called superglobals?
Other Coding Techniques

Ways to Hack
Summary
About The Author

Intended Audience
Prior to PHP 4.2.0, the default value for the PHP configuration parameter register_globals was On. Many PHP programmers took advantage of the ease of use this configuration provided.

This article is intended for PHP programmers who have, in the past, relied on the register_globals On, and now wish to change their coding style to reflect the new default for this parameter. It will also be of interest to programmers using an ISP hosted PHP environment where they do not control the values of the PHP configuration file.

Introduction
I consider one of the strengths of PHP the easy learning curve. PHP allows for embedding small portions of PHP into an HTML file, allowing HTML authors to ease into the language. PHP has a very C-like syntax, allowing for easy transition of programmers familiar with C. Weak variable typing, the flexibility and power of PHP many extensions, and abundant examples and articles on the Internet also contribute to the easy learning curve for PHP.

One recent change in PHP may increase the learning curve some. With the release of PHP 4.2.0, the default value for register_globals is now Off. This takes away one of the features that made PHP so easy to learn (a problem which it is the goal of this article to rectify).

Why was this done? In a word: security. You code is inherently more stable when you initialize and know where each variable in your source is coming from. Caution must always be taken when receiving input from a user, and allowing the user to arbitrarily make variables in your code is not good coding practice. This is perhaps better explained by the PHP developers themselves in http://www.php.net/release_4_1_0.php (see the section titled SECURITY: NEW INPUT MECHANISM) and http://www.php.net/manual/en/security.registerglobals.php.
register_globals
The register_globals configuration parameter is controlled in your php.ini file. See http://www.php.net/manual/en/configuration.php for more information on the configuration file. The register_globals parameter http://www.php.net/manual/en/configuration.php#ini.register-globals can take two values, On or Off. Prior to PHP version 4.2, On was the default, but this has now changed, and modifying your coding to accommodate this change is the subject of this article.

How do the variables get to PHP?
Experienced PHP programmers who have used URL query parameters, forms and cookies will find this section redundant, and may wish to go directly to the section on superglobals.

Variables come from many sources. Once source is initializing them yourself, $var = ’value’;. Described in the following sections are several other ways to get variables into your script, including as part of the URL, a form, a cookie, or part of the environment the server runs in. These examples are described from the perspective of a server using register_globals On, and you will learn later in the article how and where to get these values with register_globals Off.

From the URL
One of the most common ways to get information is by passing query parameters. The following is the anatomy of a URL (for more information on parsing a URL in PHP see http://www.php.net/manual/en/function.parse-url.php ):




Scheme controls the protocol used by the client and server for the request. Http and https are the most common protocols used, but you might specify another like ftp.
User and password information for basic HTTP authentication can be passed as part of the URL.
Host is the IP address or DNS name for the server reference by this URL.
Port is the TCP/IP port to use on the server, 80 is standard for HTTP, and 443 is standard for HTTPS.
Path is the location and name of the script on the server.
Query is parameters passed by the URL.
Fragment is the scroll target within the HTML document.
The portion of the URL we are most interested in here is the query parameters portion. With the register_globals On, the script.php would automatically have $var = ’val’; and $foo = ’bar’; set as global variables for the script to access.

Whenever a query parameter is specified in the script’s URL, PHP will create a global array called $HTTP_GET_VARS. This is an associative array of the key => value pairs from the URL query parameters. From the example above, PHP will automatically create $HTTP_GET_VARS = array (’var’ => ’val’, ’foo’ => ’bar’);.

Since PHP 4.1.0, a global variable called $_GET will contain the same array as $HTTP_GET_VARS. This array is a superglobal and will be discussed in greater detail later in this article.

From a Form
Another very common way to get input variable to a script is from a form on a web page. Included below is an example of how a web page might render, including the HTML source:


When a user clicks the "Send!" button, the browser will submit the form to script.php with a post variable called $foo having the value the user entered into the text box on the web form. With register_globals On, the script.php would have $foo = ’bar’; available as a global variable by default.

Similar to the query parameter example, whenever a browser submits a form to a PHP script, PHP will automatically create $HTTP_POST_VARS as an associative array of key => value pairs for all of the form inputs. The example above would result in the automatic creation of $HTTP_POST_VARS[’foo’] = ’bar’;.

With PHP 4.1.0 and greater, the variable $_POST will contain the same associative array.

From a Cookie
Web pages by nature are stateless, meaning that each time a web page is retrieved it is generated using information passed in the request. This fact presented a challenge for early web development, where designers wanted to maintain state throughout an entire interaction with a user, possibly across many web page requests on the site. The concept of cookies was developed to pass the information required to maintain this state, both for the duration of the user’s current browsing session, and longer term by "dropping" a cookie on the user’s hard drive.

If the following code was placed on a script, before any other output was sent, a cookie will be set:

/* Set Cookie for 1 day */
setcookie(’foo’, ’bar’, time()+86400, ’’, $HTTP_HOST);

Note: Astute observers will notice an obsolete global variable in the $HTTP_HOST used in the example. With register_globals = ’off’, this would need to be $_SERVER[’HTTP_HOST’].

A link on this page, to the same server, will pass $foo = ’bar’; as a cookie variable for the script.

From the Environment or the Server
The operating system environment, and the web server, has many variables that can be used by the script. One of the most common uses of a server variable is to retrieve the name of the script itself or, as in the example above, the name of the host.

PHP creates additional associative arrays as $HTTP_ENV_VARS and $HTTP_SERVER_VARS. After PHP 4.1.0, these same arrays are defined in $_ENV and $_SERVER.

Use the superglobals!
Now that you understand how these variables get to PHP, and that they are not automatically created for you by PHP when the register_globals setting Off, it is time to identify what you can do with your coding style to adjust to the new default.

Your first choice is to use the new superglobal arrays, after all, that is what they were added for! This should be your preferred method, especially if you only intend to use the value once in your script (print ’Your IP Address is:’ . $_SERVER[’REMOTE_ADDR’]; ).

If you intend to use a value more than once, you can assign the value to a variable ($mode = $_GET[’mode’]; ) instead of explicitly referencing the superglobal each time.

Why are they called superglobals?
Normally, any variable used in a function is local in scope to that function. This means if you wanted to use the global $HTTP_GET_VARS array values in a function, you would need to first use the statement global $HTTP_GET_VARS; before referencing this array.

Superglobals are an exception to this rule. You may use the variables $_GET, $_POST, $_COOKIE, $_ENV, $_SERVER and $_SESSION without having to reference them as globals first. There is also one additional superglobal array, $_REQUEST. This array contains all of the variables from GET, POST or COOKIE methods (basically anything that could be sent by the user, and which is therefore suspect).

Note: You cannot use a variable variable to access the superglobal arrays in functions. For example, the following code will not work:

<?php
function foo()
{
$sg = ’_GET’;
return ${$sg}[$var];
}
?>

the foo() function described above will not return values from the $_GET superglobal array.

Other Coding Techniques
I found myself wanting to revert back to the easy way of having my variables registered for me. However, knowing the security risks, I instead wrote some helper functions to ease the transition.

The first function I wrote was register() :
<?php
/**
* return a value from the global arrays
*
* @author Jason E. Sweat
* @since 2002-02-05
* @param string $varname
* the name of the variable to register
*
* @param string $defval optional
* the value to return if not found
*
* @return string the value of the variable if
* registered, else the default
*/
function register($varname, $defval=NULL)
{
if (array_key_exists($varname, $_SERVER)) {
$retval = $_SERVER[$varname];
} elseif (array_key_exists($varname, $_COOKIE)) {
$retval = $_COOKIE[$varname];
} elseif (array_key_exists($varname, $_POST)) {
$retval = $_POST[$varname];
} elseif (array_key_exists($varname, $_GET)) {
$retval = $_GET[$varname];
} elseif (array_key_exists($varname, $_ENV)) {
$retval = $_ENV[$varname];
} else {
$retval = $defval;
}

return $retval;
}
?>


This function now allows you to "register" variables you expect to have passed to the script. I normally use this by doing $mode = register(’mode’);. The function is defined to follow the default variables_order parameter from the php.ini file (http://www.php.net/manual/en/configuration.php#ini.variables-order ), and therefore will return an identical result to PHP with register_globals on (if assigned to a variable with the same name as you are registering). This function also allows you to specify a default value you would like to have the variable initialized with if the value is not found in any of the superglobal arrays.

This function had one drawback, it will always return a value, and therefore always initialize a variable to something. I had some instances in my code where I wanted to use isset() to determine if a value had been passed. In order to accommodate this behavior, I used a different function to register the values.

<?php
/**
* set a global variable if the specified get
* or post var exists
*
* @author Jason E. Sweat
* @since 2002-04-25
* @param string $test_vars
* the array of the vars to
* register, will accept a string
* name for a single var as well
*
* @global the variable, if it is set
*/
function getpost_ifset($test_vars)
{
if (!is_array($test_vars)) {
$test_vars = array($test_vars);
}

foreach($test_vars as $test_var) {
if (isset($_POST[$test_var])) {
global $$test_var;
$$test_var = $_POST[$test_var];
} elseif (isset($_GET[$test_var])) {
global $$test_var;
$$test_var = $_GET[$test_var];
}
}
}
?>


This function will allow you to pass an array of strings for variables to register. If any of the variable were passed in either the GET or POST methods, they will be set as global values, otherwise you will still be able to check the values using isset() to see if they were passed.

This function is also particularly good for writing a form handler script since you can initialize an array of values easily (getpost_ifset(array(’username’, ’password’, ’password2’)); ).

Ways to Hack
I can already hear the excuses: "I don’t have enough time", or "The program is third party code and I do not want to learn and maintain it".

If you must hack your way around the register_globals Off default value, I would suggest reading up on the import_request_variables() function (http://www.php.net/manual/en/function.import-request-variables.php) or reviewing some of the reader posted comments related to the extract() function (http://www.php.net/manual/en/function.extract.php).

Summary
You should now be familiar with the various means of getting variables into a PHP script, and a variety of coding methods available to you to accommodate the change of the register_globals default from On to Off. Best of luck to you, and happy (and secure) coding!

About The Author
Jason has worked as an IT professional since graduating from Colorado State University in 1992. He is currently an application developer, and the web master, for a business unit of a fortune 100 company, and maintains a server at home for educational and home business purposes. He currently resides in Iowa with his wife and two children. Please feel free to post any comments or questions below, or send them to jsweat_php@yahoo.com.
  对我一点用处没有啊,我知道该怎么学,但是我想如何才能更快的学,一周速成,啊不,24小时速成那种,皮皮你有没?
老尸 该用户已被删除
沙发
发表于 2015-2-4 09:24:08 | 只看该作者
本人接触php时间不长,算是phper中的小菜鸟一只吧。由于刚开始学的时候没有名师指,碰过不少疙瘩,呗很多小问题卡过很久,白白浪费不少宝贵的时间,在次分享一些子的学习的心得。
金色的骷髅 该用户已被删除
板凳
发表于 2015-2-9 21:15:38 | 只看该作者
在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。
小魔女 该用户已被删除
地板
发表于 2015-2-27 21:38:16 | 只看该作者
开发工具也会慢慢的更专业,每个公司的可能不一样,但是zend studio是个大伙都会用的。
只想知道 该用户已被删除
5#
发表于 2015-3-7 04:11:02 | 只看该作者
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)
海妖 该用户已被删除
6#
发表于 2015-3-10 22:49:00 | 只看该作者
你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
admin 该用户已被删除
7#
发表于 2015-3-11 06:48:17 | 只看该作者
建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。
活着的死人 该用户已被删除
8#
发表于 2015-3-11 15:51:39 | 只看该作者
基础有没有对学习php没有太大区别,关键是兴趣。
兰色精灵 该用户已被删除
9#
发表于 2015-3-18 22:59:30 | 只看该作者
这些都是最基本最常用功能,我们这些菜鸟在系统学习后,可以先对这些功能深入研究。
莫相离 该用户已被删除
10#
发表于 2015-3-22 22:09:17 | 只看该作者
作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
飘飘悠悠 该用户已被删除
11#
发表于 2015-3-24 22:35:06 | 只看该作者
小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。
因胸联盟 该用户已被删除
12#
发表于 2015-3-25 13:31:59 | 只看该作者
爱上php,他也会爱上你。
愤怒的大鸟 该用户已被删除
13#
发表于 2015-3-26 23:38:07 | 只看该作者
首先声明:我是一个菜鸟,是一个初学者。学习了一段php后总是感觉自己没有提高,无奈。经过反思我认为我学习过程中存在很多问题,我改变了学习方法后自我感觉有了明显的进步。
深爱那片海 该用户已被删除
14#
发表于 2015-3-27 11:10:56 | 只看该作者
php是动态网站开发的优秀语言,在学习的时候万万不能冒进。在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理。
再现理想 该用户已被删除
15#
发表于 2015-4-16 00:11:19 | 只看该作者
做为1门年轻的语言,php一直很努力。
小妖女 该用户已被删除
16#
发表于 2015-4-21 19:11:54 | 只看该作者
不禁又想起那些说php是草根语言的人,为什么认得差距这么大呢。
透明 该用户已被删除
17#
发表于 2015-4-26 09:11:33 | 只看该作者
如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,
简单生活 该用户已被删除
18#
发表于 2015-4-28 20:20:57 | 只看该作者
其实也不算什么什么心得,在各位大侠算是小巫见大巫了吧,望大家不要见笑,若其中有错误的地方请各位大虾斧正。
若天明 该用户已被删除
19#
发表于 2015-5-1 09:09:32 | 只看该作者
微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox  支持的不是很好,所以能少用还是少用的好。
蒙在股里 该用户已被删除
20#
发表于 2015-5-6 05:11:18 | 只看该作者
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-14 13:13

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表