SitePoint Sponsor |
|
User Tag List
Results 26 to 50 of 186
Thread: PHP and MySQL coding tips
-
Apr 2, 2002, 00:59 #26
- Join Date
- Dec 2001
- Location
- Japan
- Posts
- 655
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Your right. Guess I better redeem myself by writing it here the way I actually use it.
I use it to change the value of a specific key inside the $_POST array before entering it into mySQL.
PHP Code:for ($i = '0'; $i < count($_POST); $i++)
{
$key = array_search('on', $_POST);
$_POST[$key] = 'Yes';
}
After thinking about it, this bit of code would work only as a way to change every key with a specific value to another value... So disregard my bit of code for echoing!!.
Well, my point was that you can't loop through the $_POST array using a number for the key (at least, it wasn't working for me).
BTW, foreach is a loop.
-
Apr 2, 2002, 02:17 #27
- Join Date
- Oct 2001
- Posts
- 592
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
BTW, foreach is a loop.
that in your loop the same value is echoed everytime, whereas my loop actually traverses
the $_POST-array. But then, you set yourself straight. :-)
By the way, more often than not you can't use foreach, even though it seems nice. When
doing this:
PHP Code:foreach ($array as $key => $value) { ... }
iteration of the loop. The problem arises when you store objects (or references) inside an
array. With foreach you get a copy of every object, and not a reference to it, so
calling a method on an object that changes its state has no effect. E.g.:
PHP Code:foreach ($objects as $object)
{
$object->setSomeVariable('someValue');
}
I think the problem stems from the difference between 'passing by value' and 'passing by
reference'. Compared to Java, PHP does things a bit different. (In Java, there is no
difference; parameters are always passed by value.)
'Passing by value' in Java means that when you assign a value to an argument inside a
function, the value won't change on the outside. This is the same as in PHP. For example:
PHP Code:function test($i)
{
$i = 12;
}
$i = 8;
test($i);
echo $i; // prints '8'
by value, but you can call methods on an object inside a function that changes its value.
For example (Java):
PHP Code:void setValue(Object o, Value v)
{
o.setValue(v);
}
method on it that changes its inner state.
In PHP this doesn't work: you'd be changing the value of a copy of the object, and
not of the original object. To solve this problem, you must pass the object by
reference, as in this example:
PHP Code:function setValue(&$object, $value)
{
$object->setValue($value);
}
PHP Code:function setValue(&$object, $value)
{
$object = new Object($value);
}
only way to overcome this problem is by following programming rules like this one:
'Never assign to references passed to functions.'. Generally, it is considered bad
practice to assign to any parameter passed to a function, be it passed by value or
by reference, so this rule shouldn't too hard to follow, but still it's something you
have to enforce on yourself.
I won't say that PHP's approach to passing by value is bad, or that Java's approach is
better. PHP looks a lot more like C(++) than Java, and I personally prefer C++ above
Java (but I hate C). It's just a design decision, and one you should be aware of!
To conclude: when you use objects in PHP, you should always pass (and return!) them
by reference. When storing objects (or references) inside an array, don't use foreach to
iterate over the array elements, but use some other method instead. (See the Annotated PHP
Manual for more information on how to do this.)
Vincent
-
Apr 28, 2002, 18:10 #28
- Join Date
- Jun 2001
- Location
- In your basement
- Posts
- 1,268
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Hrm,
No one printed this before so I will...
When you are using error_reporting(E_ALL) or similar high value, you might get random errors you don't want to see.
Same with MySQL.. If there is an error, it displays if your username, and if your using a password or not.. the use of the @ symbol to silence this is good..
PHP Code:$dncnx = @mysql_query();
// Also, you can use it with variables...
if(@!$var)
{
echo('Var is not set');
}
// The above is the same as
if(!isset($var))
{
echo('Var is not set!');
}
Also, when Im doing a very basic if/else statement to assign a variable or echo, i usualy use inline statements..
PHP Code:// inline echo
$var = 5;
echo( ($var == 5) ? 'It\'s 5!' : 'It\'s Not 5 ;(');
// inline variable settings
$value = ( isset($var) ) ? $var : "NULL";
// $value will be 5
Eric Coleman
We're consentratin' on fallin' apart
We were contenders, now throwin' the fight
I just wanna believe, I just wanna believe in us
-
Apr 30, 2002, 01:53 #29
- Join Date
- Dec 2001
- Location
- Kuala Belait, Brunei
- Posts
- 367
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
converting script to no longer use globals
Does anyone know of a simple script to help fix up scripts that use globals? I've been beavering away on a PHP/MySQL site using Kevin's book which taught how to do everything using globals (not his fault...the deprecation of globals is new since he published). This leaves me with a large number of scripts which use both GET and POST globals from links and forms. Is there a script I can use to debug my scripts. Something that will list all of the globals accessed in the script and the "type" of global...ie: post or get? Can I use $GLOBALS? How?
Would this work?:
echo count($GLOBALS);
function display($ar){
while(list($key,$val)=each($ar)){
echo "<ul>";
echo "$key = $val \n\n";
if (is_array($val)){
display($val);
}
echo "</ul>";
}
}
display($GLOBALS);
Also, (here's a newbie question) do I simply convert my variables for use in my scripts like this?:
$var = $_GET['var'];
or do I use
$var = $_GET['$var'];
pPhilip Toews Professional esl Educator and ASP.NET wannabe
http://www.philiptoews.com
philip@philiptoews.com
-
Apr 30, 2002, 07:05 #30
- Join Date
- Jun 2001
- Location
- In your basement
- Posts
- 1,268
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
This is something I do myself..
In order to be ok with older versions of PHP, i still use $HTTP_*_VARS
I do this to convert them to normal values:
PHP Code:foreach($HTTP_POST_VARS as $key => $value)
{
$$key = $value;
}
$HTTP_POST_VARS['username']
will become
$username
Hope that helpsEric Coleman
We're consentratin' on fallin' apart
We were contenders, now throwin' the fight
I just wanna believe, I just wanna believe in us
-
Apr 30, 2002, 21:13 #31
- Join Date
- Jul 2001
- Location
- Missouri
- Posts
- 3,428
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Philip, i don't know of an automated way to fix your scripts.
also, since well more than a year ago, $HTTP_*_VARS has been available and has been the preferred way to access variables. Kevin's book should've used those.
BTW, i don't think that first bit of code will do anything except display all the variables that are defined. in the second bit, use the second method if you want to "shorten the name":
PHP Code:$var = $_GET['var'];
// Or assign by reference which is faster
$var = &$_GET['var'];
using either method defeats the purpose of not using register_globals, though. any variable that a user specifies will be introduced as a global variable! i want NO variable in my scripts that i didn't create (except for the predefined ones).
-
May 1, 2002, 01:22 #32
- Join Date
- Dec 2001
- Location
- Kuala Belait, Brunei
- Posts
- 367
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Clarification
Hi Larry!
I just want to make sure I understand here...before I go and assualt the dozens of scripts I have to update.
Will the following script display a list of all global variables defined in my script? I want to use it to quickly help me identify all the variables that are coming into the script. Or will it just call up the list of variables currently being passed in the current page request? I know that may sound a little silly, but I have A LOT of scripts to update and I want to do it as efficiently as possible.
I get the feeling that the only way to do this right is the hard way. Line by line making sure that nothing improper is being passed to the script.
echo count($GLOBALS);
function display($ar){
while(list($key,$val)=each($ar)){
echo "<ul>";
echo "$key = $val \n\n";
if (is_array($val)){
display($val);
}
echo "</ul>";
}
}
display($GLOBALS);
Also, I am not sure I understand the difference between the two following:
[PHP]$var = $_GET['var'];
// Or assign by reference which is faster
$var = &$_GET['var'];PHP]
What does assign by reference "do"?
TIA for any clarification
Finally, I just want to make sure I am clear on this before moving ahead. Here's what I am going to do. Can you tell me if this is right?
[list=1][*]Identify all variables that will are passed to a given script[*]Convert to safe versions using $var = $_GET['var'] or $var = $_POST['var'][*]scratch my head and wish I had done this in the first place[/list=1]
Another stupid question here. Why does converting the variables and using $_GET and $_POST help avoid security problems? I need help understanding how this works. Why does this stop a hacker from just entering in a bogus URL in order to spoof the variables. For example, if the following URL passes the variable $id:
http://www.site.com?id=1
How does converting it make any difference?
If I do this:
$id = $_GET['id']
Won't the resulting contents of $id still be whatever was in the address bar when the URL was submitted in the browser? For that matter, how does the $_POST trick protect things? Even if a hacker makes up their own form and hits the script with data, doesn't $_POST just convert whatever was sent it's way or does it actually check that it came from the right source?
Sorry to ask these silly questions, I just want to understand the "how it works' side of this security issue. It'll make me clench my teeth less when I am spending hours rewriting code I just finished!
TIA
As always Doc, you rockLast edited by Philip Toews; May 1, 2002 at 01:28.
Philip Toews Professional esl Educator and ASP.NET wannabe
http://www.philiptoews.com
philip@philiptoews.com
-
May 1, 2002, 01:35 #33
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Getting back to the general tips for a moment
Sessions
This is another area where PHP coding style has to change, now that (as of PHP 4.2) register_globals should be off.
One thing to point out first is track-vars most definately should be on (it's been on by default since PHP 4.0.3).
In the past, the way to assign variables to sessions was with session_register and session_unregister (as many tutorials like Kevin Yanks Managing Users with PHP Sessions and MySQL demonstrates.
This has changed, with register globals off.
The way to add / update session variables is now like any other array. For example, say we're handling user authentication from a form post;
PHP Code:$_SESSION[username] = $_POST[username];
$_SESSION[password] = $_POST[password];
There's a full explaination here: http://www.php.net/manual/en/ref.session.php - it's worth reading the fine print on this page.
-
May 1, 2002, 02:41 #34
- Join Date
- Oct 2001
- Posts
- 592
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
...except that it doesn't work as advertised.
If you don't do a 'session_start()' at the beginning of the script, no session data will be saved (when register_globals are off). This is true for PHP 4.2.0 on Windows and Unix.
If you follow the manual, you should never use any of the 'session_'-functions any longer, and you should only read from and assign to the $_SESSION-array. Without calling mentioned 'session_start()', this won't work, contrary to what the manual says!
Maybe in the NEXT version of PHP this will be solved...
BTW: in PHP 4.1.2 on Windows, sessions didn't work at all (with 'register_globals = off'). This caused some serious headaches, as you can imagine. Everything worked well on Unix, but it didn't on Windows. Now what? Nothing on http://bugs.php.net, so it must have been my fault... But no: install 4.1.1 or 4.2.0 and everything works again. Very nasty, those kinds of bugs...
Vincent
-
May 1, 2002, 03:26 #35
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Damn that's right. Found the bug report you were looking for here: http://bugs.php.net/bug.php?id=16043
Can see why you didn't find it - there's some screaming in there about why that bug was closed.
-
May 1, 2002, 21:57 #36
- Join Date
- Jul 2001
- Location
- Missouri
- Posts
- 3,428
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Philip, like i said, i think your "GLOBALS" code will display ALL variables that are defined, not just get/post/cookie ones. so if you had `$foo = 'bar';', $foo would be printed too.
assigning by reference makes both variables point to the same data rather than making a copy of the data. so since they both point to the same data, if you change one variable, you change both. but for trying to use a shorter variable name like in your example, there's no need to make a copy and a reference will be faster.
your steps sound correct.
about the security stuff. when register_globals is off, it doesn't matter how many variables a hacker tries to add in the URL/form/cookie, they will stay in the $_* arrays doing no harm unless you access them. when register_globals is on or you extract() the arrays, any variable that is supplied will be in your script, even though you never expected it to be. however, as i said, when they're in the arrays, they'll never affect anything! it's OK to do
$id = $_GET['id']
and i do all the time, because YOU are creating the $id variable, and you know it's from the URL since it's in the $_GET array. again though, if register_globals is on or the arrays are extract()ed, and you never used $id in your script, it would be created if `id=' was put in the URL. that's exactly what i don't want.
i hate that these global variables were ever created.it's just wrong IMO to not know where user variables came from. they should be confined to something like an array to keep them harmless; and they are when register_globals is off and you access them via these arrays -- the way, and only way, it should've been all along.
Last edited by DR_LaRRY_PEpPeR; May 1, 2002 at 22:00.
-
May 2, 2002, 05:34 #37
- Join Date
- Nov 2001
- Location
- Montreal
- Posts
- 794
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
If code is properly, and securely written, register_globals won't present a problem.
The problem is when developers don't check their variables.
PHP coders (myself included) are lazy. We don't have to worry about garbage collection, or memory allocation (for the most part), so we also let down our collective guard when it comes to variables/input, and that's why register_globals is a bad thing (usually).
It's the same reason we add slashes to any data we're sending to the database, and why we escape command characters when it comes to calling the system/shell.
That said, it IS possible to maintain security while using register globals.
I have a template (init_admin) that is called before the regular init template. It sets up some admin data.
init checks to see if $ADMIN_INIT is true, if so, carries out some admin-related code.
To make sure $ADMIN_INIT was set by me, and not by my client, I do something like this:
PHP Code:if ($ADMIN_INIT and
!isset($_GET['ADMIN_INIT'] and
!isset($_POST['ADMIN_INIT'] and
!isset($_COOKIE['ADMIN_INIT'] and
!isset($_SESSION['ADMIN_INIT'])
{
// do admin stuff
} else {
die ("ADMIN_INIT tampering");
}
S
-
May 2, 2002, 15:02 #38
- Join Date
- Jul 2001
- Location
- Missouri
- Posts
- 3,428
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
yeah, that's works and i do it. however, if register_globals never existed, or you knew it was always going to be off, you could just do
PHP Code:if ($ADMIN_INIT) { /* admin stuff */ }
-
May 2, 2002, 18:00 #39
- Join Date
- Oct 2001
- Posts
- 592
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Or, you could just do a
PHP Code:require_once('admin_init.php');
Vincent
-
May 8, 2002, 16:10 #40
- Join Date
- May 2002
- Location
- Southern California
- Posts
- 408
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Stupid question: What's the difference from grabbing the variables via global and grabbing via array? I mean, why disable globals in 4.2 by default at all
-
May 8, 2002, 16:38 #41
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Think the answer to that is two reasons.
One is security. Some people have a security system that does something like this;
1. Check username and password
2. If valid store a variable in a session like $logged_in = "yes";
3. On other pages, if $logged_in == "yes" { show them the page.
With globals on, people can get hack the security like this
http://www.yourdomain.com/secure_page.php?logged_in=yes
But with is off, only $_SESSION[logged_in] is acceptable, not $_GET[logged_in]
The other reason is one of making code make sense. With globals on, variables can be declared all over the place, and with big projects, with many files included and PHP classes, you cna have a nightmare bug fixing and updating code.
-
May 8, 2002, 19:51 #42
- Join Date
- Jun 2001
- Location
- In your basement
- Posts
- 1,268
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
That's not really true..
Becuase, I used to have something like that, but I was smart, and did
if( (isset($HTTP_POST_VARS['logged_in'])) || (isset($HTTP_GET_VARS['logged_in'])))
{
die('Nice Try @$$');
}Eric Coleman
We're consentratin' on fallin' apart
We were contenders, now throwin' the fight
I just wanna believe, I just wanna believe in us
-
May 16, 2002, 21:43 #43
- Join Date
- Jul 2001
- Posts
- 86
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I think that one useful PHP/MySQL tip that has helped me is MySQL's RAND() function, to get a random row:
SELECT * FROM myTable WHERE age > 20 ORDER BY RAND() LIMIT1
Gets one random row from myTable where the age is greater than 20. I just wish that SQL Server had this feature.Get ConMan and run your own web site!
Want free programming eBooks? http://www.devarticles.com/ebooks.php
-
Jun 2, 2002, 19:47 #44
- Join Date
- Mar 2001
- Location
- Canada
- Posts
- 98
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Here are 21 PHP tips from Zend.com that maybe should be linked from the first post in this thread:
http://www.zend.com/zend/art/mistake.php
http://www.zend.com/zend/art/mistake1.php
http://www.zend.com/zend/art/mistake2.php
-
Jun 2, 2002, 20:18 #45
- Join Date
- May 2002
- Location
- Southern California
- Posts
- 408
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Thanks Jujubee for the link
Question: Is there a difference between echo() and print()?
[added]
Checked out our favorite search engine (google) for the answer and found this post from PHPBuilder.com
there is a minute (and I do mean minute) speed difference between print and echo. Print is a function and returns a value (not a very useful one, but it returns a value nonetheless) and therefore takes just a little more time processerwise than echo, but for the most part, it is splitting hairs to tell the difference.Last edited by GeekSupport; Jun 2, 2002 at 20:21.
-
Jun 11, 2002, 05:48 #46
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Errr... well in my opinion sessions have a different purpose to cookies. But perhaps this is worth a tip;
Use sessions for users currently actively browsing your website. Sessions are there to store data that's required for the users current visit. For example storing their username / password for your sites authentication system.
Use cookies for long term data which you want to survice between visits by an individual users. For example you store their name in a cookie so that next time they come to your site, you can display "Welcome back HarryF!". The cookies would then "hand off" their data to the sessions for the current visit.
-
Jun 13, 2002, 04:21 #47
- Join Date
- May 2002
- Location
- Southern California
- Posts
- 408
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
useful link redux pointed out to me
http://www.sitepointforums.com/showt...ight=.htaccess
shows how to override php.ini settings and a snippet to save legacy code with minimal modification when upgrading to register_globals=off
-
Jun 29, 2002, 03:51 #48
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Perfect Windows Installer!
Came across an installer for Windows that just knocked my teeth out it's do good! PHP Home Edition.
It doesn't come any easier. And we're talking PHP v4.2.2, MySQL 3.23.53, Apache 2.0 and phpMyAdmin. The installer is a work of art.
Time to tell the ASP coders about it
-
Jul 4, 2002, 14:02 #49
- Join Date
- Nov 2000
- Location
- Switzerland
- Posts
- 2,479
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
PHP: Hackers Paradise Revisited
Stumbled upon this article today, from April 4th, 2001 (but it's still very applicable to the latest versions).
Full of healthy goodness like;
It seems strange to think of a web programmer as lazy. Last year most of us were working 100 hours a week to join the gold rush, now we are doing it at reduced pay just to stay afloat. In fact, we need to be lazy because we are so busy.
There are two key ways to be lazy. Firstly always use existing code when it is available, just integrate it into your standards and project. The second technique is to develop a library of helpful functions that let you be lazy in the future
The hardest thing for me to learn as a web programmer was to change the way I wrote code. Coming from a product development and university background the emphasis is on doing it the right way. Products have to be as close to perfect as possible before release. School assignments need to be perfect.
The web is different. Here it is more important to finish a project as soon as possible than it is to get it perfect first time. Web sites are evolutionary, there is no freeze date after which it is difficult to make changes.
I like to think of my web sites as prototypes. Everyday they get a little closer to being finished. I can throw together 3 pages in the time it would take to do one perfectly. It's usually better on the web to release all three and then decide where your priorities lie. Speed is all important.
So, everything you do as a programmer should be focused on the speed at which you are producing code (pages).
-
Aug 27, 2002, 13:09 #50
- Join Date
- Aug 2002
- Posts
- 4
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Checking equality and existence
A few tips from an overworked coder.
Don't use if($foo == "bar") if $foo happens to be a string...it's better to use if(strcmp($foo, 'bar')) instead.
if($foo) is a bad idea as well, especially if you have your error reporting turned to E_ALL(which you should) - instead try using if(isset($foo)) or if(!empty($foo)) or both if you need to check whether it's set AND empty
for coders who work with designers, or just for an easy system to change the design of a site with a single variable, check out http://smarty.php.net smarty is a FAST and EASY template system that uses two(optionally three) classes, just drop and go
the BEST way to comment code is to use the phpdoc format - check Pear (The Php Extension and Application Repository at http://pear.php.net/) for more info on coding standards and commenting standards
Finally, you can eek a bit more speed out of your code, especially if you have LOTS of strings, by using single quotes and concanetating variables in (I can't spell today...sigh)
$string = 'this is a string with '.$foo.' in it';
it's marginally faster than
$string = "this is a string with $foo in it";
the reason is php has to search through the string to find the variable...if you've been coding for a while and are used to the double it's not a big deal, but for those who are newbies (this is a newbie tips place, right?) it's good to learn to code right the first time instead of having to retrain or *gasp* learning bad habits.
let's see......mysql tips as well? mysql 4.0 kicks the pants off of the old mysql, upgrade if at all possible (foreign keys are coming!)
I know this has been said before, but to reiterate
REGISTER GLOBALS IS EVIL!!
single biggest cause of problems is right there....always use the HTTP_POST_VARS or better yet the $_POST, $_GET, etc. (server, session, etc, you get the drift)
ALWAYS clean user input - here's a snippet I happen to use for all my forms
OOPS, I fixed it...
PHP Code:function clean_text($text)
{
$text = strip_tags($text);
$text = htmlentities($text, ENT_QUOTES);
$text = str_replace("\n", " ", $text);
$text = eregi_replace(" +", " ", $text);
//these are optional and strip extra spaces
$text = str_replace(". ", ". ", $text);
$text = str_replace("? ", "? ", $text);
$text = str_replace("! ", "! ", $text);
$text = trim($text);
return $text;
}
somewhere is some cracker who wants to crash your site for fun...
OK, I think that's enough for today...Last edited by auroraeosrose; Aug 28, 2002 at 09:03.
Bookmarks