Personal computing discussed

Moderators: renee, SecretSquirrel, just brew it!

 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

php/mysql issue

Wed Apr 12, 2006 1:23 pm

heh. this has nothing to do with the other vb.net/sql issue i have in this section...

so this is the scoop. i have a website in which i want to record ppl logging
onto (ip, timestamp, page surfed on), and it also attaches a sessionid to
their record in the db as well (so not to get duplicates)... now...

its not working 100% the way i want it to... it's causing INSERT errors cuz
of duplicate record and CHANGE errors as well.. here's the data in the db
first of all so you can see what i'm trying to explain here:

mysql> select * from useronline order by timestamp;
+------------+-----------------+-----------------+----------------------------------+
| timestamp  | ip              | file            | online                           |
+------------+-----------------+-----------------+----------------------------------+
| 1144853539 | xxx.xx.xx.53    | /index.php | 0                                |
| 1144856005 | xxx.xx.xx.53    | /index.php | 0                                |
| 1144864184 | xxx.xx.xx.53    | /index.php | 5198c2fd76128e6498b05fe4f58d2b5b |
| 1144864218 | xxx.xx.xx.53    | /index.php | 6b577087bc9505dcbf4cda806eeeccaf |
| 1144864221 | xxx.xx.xx.53    | /contact.php | 6b577087bc9505dcbf4cda806eeeccaf |
+------------+-----------------+-----------------+----------------------------------+
5 rows in set (0.00 sec)


and here's the code:

<?
   $server="localhost";
   $db_user="xxxxxxxxxx";
   $db_pass="xxxxxxxxxx";
   $database="xxxxxxxxxx";
   $timeoutseconds=300;
   $timestamp=time();
   $timeout=$timestamp-$timeoutseconds;
   $stamp=date("F d, Y \\a\\t g:ia",$timestamp);

   session_start();
   $_SESSION[name] = $PHPSESSID;

   if (!isset($_SESSION[initiated])) {
     session_regenerate_id();
     $_SESSION[initiated] = true;
   }

   mysql_connect($server, $db_user, $db_pass);

   $query=mysql_db_query($database,"SELECT DISTINCT ip,timestamp,file,online FROM useronline WHERE online!='0' order by timestamp");
   if(!($query)) { print "Useronline Select Error > "; }

   $res=array();
   while($row=mysql_fetch_array($query,MYSQL_ASSOC)) array_push($res,$row);

   foreach ($res as $x) {
     if ($REMOTE_ADDR==$x[$ip] && $_SESSION[name]==$x[online]) {
       $change=mysql_db_query($database,"UPDATE useronline SET timestamp='$timestamp' WHERE online='".$x[online]."'");
       if(!($change)) { print "* Useronline Change Failed > <br>"; }
     } else {
       $insert=@mysql_db_query($database,"INSERT INTO useronline VALUES('$timestamp','$REMOTE_ADDR','$PHP_SELF','$_SESSION[name]')");
       if(!($insert)) { print "* Useronline Insert Failed > <br>"; }
     }
   }

   $insert=mysql_db_query($database,"INSERT INTO useronline VALUES('$timestamp','$REMOTE_ADDR','$PHP_SELF','$_SESSION[name]')");
   if(!($insert)) { print "** Useronline Insert Failed > "; }

   // not deleting records when timeout occurs, rather it saves the records and changes the sessionid to a '0'
   // --------------------------------------------------------------------------------------------------------
   // $delete=mysql_db_query($database,"DELETE FROM useronline WHERE timestamp<$timeout");
   // if(!($delete)) { print "Useronline Delete Failed > "; }

   $change=mysql_db_query($database,"UPDATE useronline SET online='0' WHERE timestamp<$timeout");
   if(!($change)) { print "** Useronline Change Failed > "; }

   mysql_close();
?>


and the sql schema if u need it:

CREATE TABLE useronline (
    timestamp int(15) DEFAULT '0' NOT NULL,
    ip varchar(40) NOT NULL,
    file varchar(100) NOT NULL,
    online text NULL,
    PRIMARY KEY (timestamp),
    KEY ip (ip),
    KEY file (file)
);

mysql> describe useronline;
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| timestamp | int(15)      |      | PRI | 0       |       |
| ip        | varchar(40)  |      | MUL |         |       |
| file      | varchar(100) |      | MUL |         |       |
| online    | text         | YES  |     | NULL    |       |
+-----------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)


k... and i get these errors:

when the update error occurs, i get:

ERROR 1062: Duplicate entry '1144864221' for key 1

when the insert error occurs, i get:

ERROR 1062: Duplicate entry '1144864221' for key 1


is it cuz i'm working with timestamps and i defined it as the primary key?
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Wed Apr 12, 2006 1:29 pm

Does the error always occur or only sometimes?

Seems to me that using the timestamp as a primary key will cause problems whenever two records happen to have the same timestamp...
Nostalgia isn't what it used to be.
 
Capsaicin
Gerbil XP
Posts: 367
Joined: Thu Feb 02, 2006 10:57 am

Re: php/mysql issue

Wed Apr 12, 2006 1:43 pm

thegleek wrote:
i'm working with timestamps and i defined it as the primary key

:lol: :lol: :lol:
 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

Wed Apr 12, 2006 1:47 pm

dammit. and that very solution came to me after i post all that here
and visually saw how the primay key was the timestamp! haha ok now
the question is how to i enter the ALTER TABLE command to drop the
primary key from the timestamp field and create another field called id
or key or something and make that the primary without **** up the current data!? :o
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
Capsaicin
Gerbil XP
Posts: 367
Joined: Thu Feb 02, 2006 10:57 am

Wed Apr 12, 2006 1:53 pm

Create a new table with the same structure + new column. Insert the data into the new table from the old one. Delete the old table. Rename the new table.
 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

Wed Apr 12, 2006 2:16 pm

Capsaicin wrote:
Create a new table with the same structure + new column. Insert the data into the new table from the old one. Delete the old table. Rename the new table.


nah, phpmyadmin ftw!
Table useronline has been altered.  

SQL query:

ALTER TABLE `useronline` ADD `id` INT( 15 ) NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST ;
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

Wed Apr 12, 2006 2:36 pm

ok, removing the primary key from timestamp and adding another
field called id with primary key seemed to solved the problem from me getting those errors...

but it still wont updated the SAME record that has the SAME sessionid

it keeps creating new records dammit!

HELP!

mysql> select * from useronline order by timestamp;

+----+------------+-----------------+-----------------+----------------------------------+
| id | timestamp  | ip              | file            | online                           |
+----+------------+-----------------+-----------------+----------------------------------+
| 30 | 1144864918 | xxx.xx.xx.53    | /index.php | 0                                |
| 43 | 1144869180 | xxx.xx.xx.53    | /index.php | 921104b46d5e95c08d0876de625d76bb |
| 44 | 1144869181 | xxx.xx.xx.53    | /aboutus.php | 921104b46d5e95c08d0876de625d76bb |
| 45 | 1144869181 | xxx.xx.xx.53    | /index.php | 921104b46d5e95c08d0876de625d76bb |
| 46 | 1144869183 | xxx.xx.xx.53    | /contact.php | 921104b46d5e95c08d0876de625d76bb |
| 47 | 1144869183 | xxx.xx.xx.53    | /index.php | 921104b46d5e95c08d0876de625d76bb |
| 48 | 1144869183 | xxx.xx.xx.53    | /contact.php | 921104b46d5e95c08d0876de625d76bb |
+----+------------+-----------------+-----------------+----------------------------------+
7 rows in set (0.00 sec)
:evil:
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
Capsaicin
Gerbil XP
Posts: 367
Joined: Thu Feb 02, 2006 10:57 am

Re: php/mysql issue

Wed Apr 12, 2006 4:50 pm

thegleek wrote:
CREATE TABLE useronline (
timestamp int(15) DEFAULT '0' NOT NULL,
ip varchar(40) NOT NULL,
file varchar(100) NOT NULL,
online text NULL,
PRIMARY KEY (timestamp),
KEY ip (ip),
KEY file (file)
);

Hint: text fields are like C-style pointers :lol:
 
cubical10
Gerbil First Class
Posts: 184
Joined: Fri Mar 03, 2006 2:52 pm
Location: Montreal

Wed Apr 12, 2006 6:11 pm

It sounds like you want to have 1 record per IP/Session pair.

First you could make your db do a bit more of the work.

Use the datetime datatype for your `timestamp` column. You might want to rename it as well as timestamp is also a datatype, maybe `dateStamp`.

You could also use the mysql functions INET_ATON()/INET_NTOA() to convert the dotted-quad to an int and therefore change the `ip` column datatype to int, and again `ipAddress` is a more descriptive field name.

I am pretty sure that all PHP session id are 32 chars (they are a MD5 hash iirc) so you could save a bit of db space by changing the datatype to varchar(32) or 40 to be safe.

Finally, you could create a 2 column primary key on ip and online, removing the need for an extra column and preserving the 1 record per IP/Session pair rule that it looks like you want.

Here is the statment to create the table:
CREATE TABLE `useronline` (
`ipAddress` int(11) NOT NULL,
`dateStamp` datetime NOT NULL,
`file` varchar(100) collate latin1_general_cs NOT NULL,
`sessionID` varchar(32) collate latin1_general_cs NOT NULL,
PRIMARY KEY (`ipAddress`,`sessionID`)
) ENGINE=MyISAM;
------------------------------------------
Now to the PHP part...
After you db connection is set up you should be able to use this sql statement to insert, i say should as there may be a typo...
$sessionID = session_id();
$sql = "insert into `useronline` values
(INET_ATON('{$_SERVER['REMOTE_ADDR']}'),
now(),
{$_SERVER['PHP_SELF']},
'$sessionID');";

Now you can either use mysql_error() to check to see if there was an error inserting the record, and if so send an update statement instead. Its ugly and lazy but works...
Or of course a simple "select from `useronline` where `ipAddress`=INET_ATON('{$_SERVER['REMOTE_ADDR']}') and `sessionID`='$sessionID';".
Then use mysql_num_rows to see if you have a match and if so send the update query, if not the insert query.

No matter what make it a function (or class) and save it in a seperate file and use require_once() in all files to save on copy/paste and make it easy to update in the future.

Hope this helps...
Cubical 10
I only know enough to be dangerous.

Do ubuntu? pfsense
 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

Thu Apr 13, 2006 10:35 am

cubical10 wrote:
No matter what make it a function (or class) and save it in a seperate file and use require_once() in all files to save on copy/paste and make it easy to update in the future.


woo nice post there! sounds like you've been around the block a few times
with this stuff.. but i notice a java/vb.net mindset to your style. in php,
or many languages, one does not need to always follow those standards
in naming variables or fields in that manner.. (ie: gerbilForm, postString)

also, php isn't much of a OOP language nor does it need to be, sure
programming classes and functions are nice, but not really necessary. i
do agree it's a better programming style however. and definately easier
to update and change things as well...

but i've fixed my issue and it's sorta what cubical10 just mentioned about
doing a query, then a count, then deciding on whether to do an update or an insert.

   $cq=mysql_db_query($database,"select count(*) from useronline where online!='0'");
   if(!($cq)) { print "Useronline 'select count(*)' Error > <br>"; }
   $cr=mysql_fetch_row($cq);
   $cr=$cr[0];

   if ($cr) {
     $flag=0;
     $res=array();
     while($row=mysql_fetch_array($query,MYSQL_ASSOC)) array_push($res,$row);

     foreach ($res as $x) {
       if ($REMOTE_ADDR==$x[ip] && $_SESSION[name]==$x[online]) { $flag=1; }
     }

     if ($flag) {
       $change=mysql_db_query($database,"UPDATE useronline SET timestamp='$timestamp',file='$PHP_SELF' WHERE online='".$_SESSION[name]."'");
       if(!($change)) { print "* Useronline Change Failed > <br>"; }
     } else {
       $insert=mysql_db_query($database,"INSERT INTO useronline VALUES(NULL,'$timestamp','$REMOTE_ADDR','$PHP_SELF','$_SESSION[name]')");
       if(!($insert)) { print "* Useronline Insert Failed > <br>"; }
     }
   } else {
     $insert=mysql_db_query($database,"INSERT INTO useronline VALUES(NULL,'$timestamp','$REMOTE_ADDR','$PHP_SELF','$_SESSION[name]')");
     if(!($insert)) { print "** Useronline Insert Failed > "; }
   }
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
Flying Fox
Gerbil God
Posts: 25690
Joined: Mon May 24, 2004 2:19 am
Contact:

Thu Apr 13, 2006 11:02 am

Even in non-OOP languages, there is merit in following an organized naming convention and code structuring. Readability and maintainability are also important factors in "real world" software development, sometimes even more so than just pure performance (like the user is going to notice a difference if a certain operation is going to take them 0.1s more? :roll:).

Fast and loose coding styles is one of the reasons why pet/opensource projects are getting bad rep. Also, it is a good practice for programmers anyway, so why use 2 different coding styles for different projects?
 
cubical10
Gerbil First Class
Posts: 184
Joined: Fri Mar 03, 2006 2:52 pm
Location: Montreal

Thu Apr 13, 2006 11:35 am

thegleek wrote:
i notice a java/vb.net mindset to your style. in php,
or many languages, one does not need to always follow those standards
in naming variables or fields in that manner.. (ie: gerbilForm, postString)


I cut my web teeth with PHP/MySQL and absolutley love working in a L.A.M.P evironment. But as of late I have been switching to the .Net environment as that is the preference at my place of work. So it definately has had an influence on my coding style.

To be stubborn...
I strongly suggest that you create a functions.inc.php file and place reusable code in it. It doen't have to be a class, but this little bit of code that will probably be placed in all of your files wreaks of being a function.

Use useful relevant names for you variables, no matter what language you are working in.

Let the DB do the db stuff, why have PHP calcuate the current time, save it to a variable and then pass it to MySQL? Just use one of the three date/time datatypes in MySQL and use now().

Finally, using the old PHP constants like $REMOTE_ADDR and $PHP_SELF is depricated and will stop working at sometime in the future. Use $_SERVER[].
Cubical 10
I only know enough to be dangerous.

Do ubuntu? pfsense
 
thegleek
Darth Gerbil
Topic Author
Posts: 7460
Joined: Tue Jun 10, 2003 11:06 am
Location: Detroit, MI
Contact:

Thu Apr 13, 2006 12:01 pm

cubical10 wrote:
Finally, using the old PHP constants like $REMOTE_ADDR and $PHP_SELF is depricated and will stop working at sometime in the future. Use $_SERVER[].

ORLY?

cubical10 wrote:
I cut my web teeth with PHP/MySQL and absolutley love working in a L.A.M.P evironment.

excuse my ignorance, but mind explaining this LAMP thing or give me
a good url to check out... never heard of it... then again, 50 new concepts
come out every month, so how can one keep up!?
––•–√\/––√\/––•–– nostalgia is an emotion for people with no future ––•–√\/––√\/––•–-
 
cubical10
Gerbil First Class
Posts: 184
Joined: Fri Mar 03, 2006 2:52 pm
Location: Montreal

Thu Apr 13, 2006 12:41 pm

$_SERVER is a super global array. It contains most of what you have been using, but as keys in an array.
Create this file:
<pre>
<?php
print_r($_SERVER);
?>
</pre>


LAMP => Linux Apache MySQL PHP
Cubical 10
I only know enough to be dangerous.

Do ubuntu? pfsense
 
Flying Fox
Gerbil God
Posts: 25690
Joined: Mon May 24, 2004 2:19 am
Contact:

Thu Apr 13, 2006 2:03 pm

cubical10 wrote:
LAMP => Linux Apache MySQL PHP

I thought the P can mean Python or Perl too? :roll:
 
cubical10
Gerbil First Class
Posts: 184
Joined: Fri Mar 03, 2006 2:52 pm
Location: Montreal

Thu Apr 13, 2006 2:14 pm

I think that the new/proper/ga term is now xamp.

Where x is any unix variant and the p is for php or perl.
Cubical 10
I only know enough to be dangerous.

Do ubuntu? pfsense
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Thu Apr 13, 2006 11:59 pm

Flying Fox wrote:
cubical10 wrote:
LAMP => Linux Apache MySQL PHP

I thought the P can mean Python or Perl too? :roll:

My understanding was that P = PHP... but yeah apparently it can also mean Python/Perl as well (but AFAIK this is a less common interpretation).

cubical10 wrote:
I think that the new/proper/ga term is now xamp.

Where x is any unix variant and the p is for php or perl.

Actually, the x can also be Windows! There are Windows ports of Apache, PHP/Perl/Python and MySQL. :wink:
Nostalgia isn't what it used to be.
 
Flying Fox
Gerbil God
Posts: 25690
Joined: Mon May 24, 2004 2:19 am
Contact:

Fri Apr 14, 2006 12:01 am

just brew it! wrote:
Actually, the x can also be Windows! There are Windows ports of Apache, PHP/Perl/Python and MySQL. :wink:

I think they call it WAMP?
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Fri Apr 14, 2006 12:03 am

Flying Fox wrote:
I think they call it WAMP?

Yes, I know WAMP specifically refers to the Windows flavor. But wouldn't XAMP imply that the OS can be anything?
Nostalgia isn't what it used to be.
 
Flying Fox
Gerbil God
Posts: 25690
Joined: Mon May 24, 2004 2:19 am
Contact:

Fri Apr 14, 2006 12:06 am

just brew it! wrote:
Flying Fox wrote:
I think they call it WAMP?

Yes, I know WAMP specifically refers to the Windows flavor. But wouldn't XAMP imply that the OS can be anything?

If you define any letter as a "variable", then it can be any letter in the alphabet! :D
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Fri Apr 14, 2006 12:10 am

Well, X usually means "substitute something here". :wink:
Nostalgia isn't what it used to be.
 
morphine
TR Staff
Posts: 11600
Joined: Fri Dec 27, 2002 8:51 pm
Location: Portugal (that's next to Spain)

Fri Apr 14, 2006 2:50 am

I always thought it meant "X marks the spot".

Who is online

Users browsing this forum: No registered users and 6 guests
GZIP: On