-1

I have been searching for days for a solution to a code I am trying to create in PHP.

I have this game where the names of the players and guests are updated in a database, every 5 seconds along with the timeframe they have been active in the game, similar to the example below:

$players = "Jennifer,2016-02-14 10:41:02|Don,2016-02-14 11:41:02|Scoop,2016-02-14 10:41:02|";

I would like to loop through $players and remove any name along with the timeframe where it shows that the player has been inactive for 3 minutes, based on the current time.

I really hope that my question is clear enough and that someone out there could point me in the right direction. I would greatly appreciate it.

$game_id=1; $name='Jennifer';

//First I select all of the players in the game

$sql = 'SELECT players FROM gamesvalues WHERE game_id=?'; /* Prepare statement */

$stmt = $conn->prepare($sql);if($stmt === false) {

trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);

} /* Bind parameters. TYpes: s = string, i = integer, d = double, b = blob */

$stmt->bind_param('i',$game_id);

/* Execute statement */

$stmt->execute();

$stmt->bind_result($players);

while ($stmt->fetch())

 //Next find out if the name "Jennifer" exists or positioned in players list

$pos = strpos($players, $name);

if ($pos === false) {

echo "The string '$name' was not found in the string '$guests'";

} else {

//Once the player's position is found,use substr and strpos to seperate the
//player's name and active time from the list

$activeplayer= substr($players,$pos, strpos($players, '|'));

//Then use explode to find the active time of the player

$playertime = explode(",", "$activeplayer");

$lastactive_time=strtotime($playertime[1]);

$current_time = strtotime(date("h:i:sa"));

//Since I have a time limit of 3 mins for inactive players to be in game,
//I subtract the last active time of the player from the current time using strotime
//If the time is greater than 3 minutes, I remove the player by using str_replace

$timedifference=round(abs($lastactive_time - $current_time) / 60);

if ($timedifference>3)

$newusr=str_replace($activeplayer.'|',"",$players); }

Emac
  • 9
  • 1
  • any effort on your side? – Kevin Kopf Feb 14 '16 at 23:38
  • Nordenheim is right, show at least your code! – CodeIsLife Feb 14 '16 at 23:40
  • 3
    take a step back and store the data in a useabel format –  Feb 14 '16 at 23:42
  • Yeah, remake your database. Your format is really messed up. And @Dagon, whenever I read "take a step back" it makes me remember the skyrim shuffle – Phiter Feb 14 '16 at 23:51
  • 1
    @PhiterFernandes i had to google that, i hate you :-) https://www.youtube.com/watch?v=b1y-CCqeRiQ –  Feb 14 '16 at 23:54
  • @Dagon Not sure what you mean by "store the data in a useabel format. But the user along with their active time are stored in field called players. – Emac Feb 15 '16 at 00:51
  • [db normalization](https://en.wikipedia.org/wiki/Database_normalization) really important if your site growss –  Feb 15 '16 at 02:05

2 Answers2

0

There are many methods to extract desired values from your players fields: you can find the strpos of , and | and then extract the pieces through substr, or you can explode string by | and then explode each row by ,, but the speediest way is to use regular expression:

$pattern = '/([^,]+),([^|]+)\|/';
preg_match_all( $pattern, $players, $matches );

By this way, each substring matching pattern $pattern is captured in $matches array, in which you have the entire pattern at index [0], the first parenthesis group at index [1] and the second parenthesis group at index [2].

The above $pattern means:

(
    [^,]+   One or more characters excluding comma
)
,           Comma (not grouped)
(
    [^|]+   One or more characters excluding vertical bar
)
\|          Vertical bar (not grouped)

To match vertical bar, they must be escaped, because regex use unescaped vertical bar as OR operator; in the second group it is not escaped due to prepended caret (^).

You can obtain identical result using Question mark as ungreedy modifier, but I chose above syntax for greater clarity.

At this point, you have in $matches following array:

Array
(
    [0] => Array
        (
            [0] => Jennifer,2016-02-14 10:41:02|
            [1] => Don,2016-02-14 11:41:02|
            [2] => Scoop,2016-02-14 10:41:02|
        )

    [1] => Array
        (
            [0] => Jennifer
            [1] => Don
            [2] => Scoop
        )

    [2] => Array
        (
            [0] => 2016-02-14 10:41:02
            [1] => 2016-02-14 11:41:02
            [2] => 2016-02-14 10:41:02
        )

)

and you can process $matches[2] to compare values with actual time.

This regular expression can also help you if you decide to convert actual data in a more suitable database structure.


Community
  • 1
  • 1
fusion3k
  • 11,568
  • 4
  • 25
  • 47
  • This looks like it could work. Gonna check it out and post my results. Sorry I am fairly new to PHP, so I was wasn't sure how to approach it codewise. This is why I wasn't able to provide an example. Thanks for your help – Emac Feb 15 '16 at 01:05
0
<?php

function remove_the_name( $name, $player ){
    $player = explode( "|", $player );
    foreach( $player as $key => $one_player ){
        $players[$key] = explode( ",", $one_player );
    }
    $key = get_the_key_of_uname( $name, $players );
    $str = "";

    $i = 1;
    foreach( $key as $s => $e ){
        $i++;
        if( is_array( $e ) ){
            $str .= implode(",",$e);
        }
        if( count($key) < $i ){

        }else{
            $str .= "|";
        }   

    }
    echo $str;
}

function get_the_key_of_uname( $name, $players ){
    foreach( $players as $id => $player ){
        $key = array_search( $name, $player );
        if( $key !== false ){
            $e = $id;
            break;
        }       
    }
    unset( $players[$id] );
    return $players;
}

remove_the_name( "Scoop", "Jennifer,2016-02-14 10:41:02|Don,2016-02-14 11:41:02|Scoop,2016-02-14 10:41:02|" );
?>

I wrote this full function, this will be easy for you. :)

hemnath mouli
  • 2,617
  • 2
  • 17
  • 35