Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Reo
Apr 11, 2003

That'll do, Carlos.
That'll do.


I have a question that's bugging me in that I've seen it done, but can't achieve it myself.

I want to have a search form that selfposts to the same page to display the search results. I am trying to use Post>Redirect>Get to avoid the forward/back button resubmit prompt. I got that part working.

However, the kicker is that I can't figure out how to achieve this without querystring parameters. I've attempted storing the search terms in the session, but then when navigating back through past searches, they all appear as whatever the latest session terms are.


In essence, what I want:

search.php -> User submits "Apple"
search.php -> Results for Apple. user submits "Banana"
search.php -> Results for Banana. User submits "Orange"
search.php -> Results for Orange. User clicks "back"
search.php -> Results for Banana. User clicks "back"
search.php -> Results for Apple.

By storing the search terms in the session, what I got was:

search.php -> User submits "Apple"
search.php -> Results for Apple. user submits "Banana"
search.php -> Results for Banana. User submits "Orange"
search.php -> Results for Orange. User clicks "back"
search.php -> Results for Orange. User clicks "back"
search.php -> Results for Orange.

Adbot
ADBOT LOVES YOU

Yay
Aug 4, 2007
What's the rationale behind using POST for search, over GET? POST [should] imply a modification to the system, and is not shareable in any easy way. Seems like an over-complication that is unnecessary and not desirable.

Reo
Apr 11, 2003

That'll do, Carlos.
That'll do.


Perhaps the searches are logged in a database, I'm not sure. Like I said, I saw a site that uses that model and was wondering how they accomplished it; I don't know their reasons.

Edit: here's the page, to show what I mean:
http://www.acparadise.com/ace/search.php (try searching Bill, then Joe, and going back/forward)

Reo fucked around with this message at 18:38 on Mar 19, 2011

Yay
Aug 4, 2007

Reo posted:

Edit: here's the page, to show what I mean:
http://www.acparadise.com/ace/search.php (try searching Bill, then Joe, and going back/forward)
Chrome asks me to reconfirm form submissions, and the network tab in the developer toolbox doesn't show any redirects occuring, just the POST request's response.

Reo
Apr 11, 2003

That'll do, Carlos.
That'll do.


Yay posted:

Chrome asks me to reconfirm form submissions, and the network tab in the developer toolbox doesn't show any redirects occuring, just the POST request's response.
Seriously? Weird. Neither Chrome nor Firefox asks me for a resubmit confirm.

Is it possible the browser is caching the POSTed pages or something?

Reo fucked around with this message at 19:52 on Mar 19, 2011

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.

Reo posted:

Seriously? Weird. Neither Chrome nor Firefox asks me for a resubmit confirm.

Is it possible the browser is caching the POSTed pages or something?

You may want to check they don't submit an empty query. I was able to seriously bog down your server by just clicking Search.

Reo
Apr 11, 2003

That'll do, Carlos.
That'll do.


musclecoder posted:

You may want to check they don't submit an empty query. I was able to seriously bog down your server by just clicking Search.
I know, but it's not my site. :)

bobthecheese
Jun 7, 2006
Although I've never met Martha Stewart, I'll probably never birth her child.
In general, for searches, you should always use GET (or some variation thereof) Either way, the search should be stored in the URL in one way or another.

The effectiveness of a search page is greatly reduced it you can't pass it around or bookmark it. Want to show a friend something on page three of your search for apples? Would you prefer to send them a URL to the search page, or send them a URL to the site with the instructions "Search for apples, go to page 3"

You don't NEED to have ugly query strings in your URL. Using mod_rewrite, it's easy enough to turn site.com/search.php?term=apples&page=3 into site.com/search/apples/3/.

Reo
Apr 11, 2003

That'll do, Carlos.
That'll do.


Yeah, I know, that makes sense. I was curious how they managed it though. Thanks anyway, on to more important questions!

ryo
Jan 15, 2003
I have a database with some fields that have a bunch of Enum values, and a function that queries the database for these values and returns them in an array so they can be used in an HTML drop down list.
The query returns something like
code:
enum('value1','value2','value3)
And I just move those values into an array and return it. It just seems like this is very un-elegant way of doing this. I'm using CodeIgniter by the way. Is there a built-in function in CodeIgniter, or a better SQL query I could use? Here's my function:

php:
<?
function get_enum_list($table,$field)
    {
        $sql = "SHOW COLUMNS FROM `$table` LIKE '$field'";
        
        $query = $this->db->query($sql);

        if ($query) {
            $row = $query->row();

            $list = substr($row->Type,6,-2);
            $list = str_replace("','",",",$list);
            $listarray = explode(",",$list);

            return($listarray);
        }
        else {
            return FALSE;
        }

        
    }?>

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Assuming MySQL from the SHOW command... http://forums.mysql.com/read.php?10,192224,192231#msg-192231 suggests that the more standard way to do that (i.e. using INFORMATION_SCHEMA) is

code:
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '$database' AND TABLE_NAME = '$table' AND COLUMN_NAME = '$field'
Experimentation on my own database suggests that that will give you the same output as your current query.

It seems like your current function would cause you problems if you had an ENUM value containing a comma. Consider

code:
ENUM ('Lemons','Apples','Houston, we have a problem')
Surely your function would return

code:
array( 'Lemons',
       'Apples',
       'Houston',
       ' we have a problem'
       )
So I suggest

code:
function get_enum_list ($database, $table, $field) {
    $sql = "SELECT
                COLUMN_TYPE
            FROM
                INFORMATION_SCHEMA.COLUMNS
            WHERE
                TABLE_SCHEMA = '$database' AND
                TABLE_NAME = '$table' AND
                COLUMN_NAME = '$field'";
    $query = $this->db->query($sql);
    if ($query) {
        $row = $query->row();
        $list = substr($row->COLUMN_TYPE, 6, -2);
        return explode("','", $list);
    } else {
        return FALSE;
    }
}
Of course, you still have problems if one of your ENUM values contains ',', but let us assume you would not do that.

I'm not sure there is a way to get it more "elegant" than that.

e: I know nothing about CodeIgniter.

Hammerite fucked around with this message at 19:27 on Mar 20, 2011

musclecoder
Oct 23, 2006

I'm all about meeting girls. I'm all about meeting guys.
I would suggest you not use an ENUM column, just treat it as a normal VARCHAR and store valid values in an array somewhere. Then let your application validate against those values and you can use those values in your dropdown. I've never used an ENUM and not had it come back to bite me in the rear end later.

ryo
Jan 15, 2003
Thanks, I think I'll go with varchar instead then, I hadn't considered the problem with commas in enum values (which is a possibility).

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION
Been using CodeIgniter 2.0 to recreate an existing project of mine from the ground up. It's an AFL (Australian Football League) tipping thing, where my fellow employees can log in and place their tips etc.

I'm struggling with how to structure the project. My database looks something like this (simplified):
code:
========
GAME
========
game_id
round_id
venue_id
game_date

========
TEAMGAME
========
tega_id
team_id
game_id
tega_home
tega_score

========
TEAM
========
team_id
team_name
So I'm imagining that in PHP the game object would look something like this:
code:
========
GAME
========
game_id
game_date
teams
- ['home']
-- ['team_id']
-- ['team_name']
-- ['score']
- ['away']
-- ['team_id']
-- ['team_name']
-- ['score']
venue
- ['venue_id']
- ['venue_name']
I'm just not sure how to implement this in CodeIgniter. Is there a way to define your own classes like this? I'm new to the MVC approach, so I'm not sure but one method I was thinking of would be to make this as the game model, but then CodeIgniter doesn't seem to be built to work this way.

I'm completely loving lost to be honest - how do I arrange all these objects so they make sense while still keeping the MVC structure intact?

Edit: Should these perhaps be created as libraries?

putin is a cunt fucked around with this message at 03:02 on Mar 23, 2011

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Gnack posted:

Been using CodeIgniter 2.0 to recreate an existing project of mine from the ground up. It's an AFL (Australian Football League) tipping thing, where my fellow employees can log in and place their tips etc.

I'm struggling with how to structure the project. My database looks something like this (simplified):

I'm just not sure how to implement this in CodeIgniter. Is there a way to define your own classes like this? I'm new to the MVC approach, so I'm not sure but one method I was thinking of would be to make this as the game model, but then CodeIgniter doesn't seem to be built to work this way.

I'm completely loving lost to be honest - how do I arrange all these objects so they make sense while still keeping the MVC structure intact?

Edit: Should these perhaps be created as libraries?

You can define your own classes any way you so feel. Your DB looks a little strange to me. A GAME has two TEAMS, two SCORES (one for each team), a Date played, one RoundId, and one VENUE. Each VENUE has a name, each TEAM has a NAME.

Your DB looks something like:

code:
GAME
====
id (int, primary key)
venue (int, is the VENUE id)
homeTeam (int, is the home team's id)
awayTeam (int, is a team id)
RoundId (int? not sure what this is)
date_played (datetime)
homeScore (int (or float if you have half points =))
awayScore (int)

VENUE
===
id (int, primary key)
name (varchar)

TEAM
===
id (int, primary key)
name (varchar)

and your model logic just follows the DB. One class for each table. Forgive the probably broken code, I last used CI years ago...

php:
<?
class Team extends CI_Model {

    var $name   = '';

    function __construct()
    {
        parent::__construct();
    }

   function get_team_list()
   {
      $query = $this->db->get('teams');
      return $query->result();
   }
    
    function add_team()
    {
        $this->name   = $_POST['name']; // lol, security
        $this->db->insert('teams', $this);
    }

    function get_team_name($id)
    {
       $query = $this->db->select('name')->where('id', $id)->get('teams');
        return $query->result();
    }

}
?>
GAMES is just more code, but the same gist applies, and it would call on the TEAM and VENUE models as needed to get team names and so on.

Lumpy fucked around with this message at 05:47 on Mar 23, 2011

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION
Thanks for the help. I should have explained the fields a bit better, but AFL is divided up into a set number of rounds per season, so the round_id is used to determine which round any given game belongs to. In other words, yeah, it's an INT.

I like the way you've simplified the database model, and I reckon I'll take that advice on board. Thanks!

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

ryo posted:

Thanks, I think I'll go with varchar instead then, I hadn't considered the problem with commas in enum values (which is a possibility).

Instead of enum, or a varchar field, you should use another related table and a foreign key relationship. There are all kinds of issues with having to keep a list of valid values hardcoded and then storing the value as a varchar.

I am sure you are familiar with this, but just in case here is an example.

Consider a user table, and each user has a favorite fruit.
code:
FavoriteFruitTable
Id         FruitName
1          Bananas
2          Strawberries
3          Apples
4          Plums
To create your dropdown you just select all the values in an array. The value of the selected option is the Id. Then in the user table you have an integer foreign key like FavoriteFruitId.

cLin
Apr 21, 2003
lat3nt.net
How would I go about breaking a phrase down from something like "The Big Red House" into an array with the values
code:
The
Big
Red
House
The Big
Big Red
Red House
The Big Red
Big Red House
The Big Red House
Basically getting every possible phrase combination without reordering the original phrase. Would it be using a combination of a loop and explode()? I know permutations create every possible combination using a set of values...what would this be called so I can look it up.

cLin fucked around with this message at 00:17 on Mar 25, 2011

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

cLin posted:

How would I go about breaking a phrase down from something like "The Big Red House" into an array with the values
code:
The
Big
Red
House
The Big
Big Red
Red House
The Big Red
Big Red House
The Big Red House
Basically getting every possible phrase combination without reordering the original phrase. Would it be using a combination of a loop and explode()? I know permutations create every possible combination using a set of values...what would this be called so I can look it up.

Searching "php permutate array" came up with lots of examples: http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=php+permutate+an+array

Elias_Maluco
Aug 23, 2007
I need to sleep
So I have this site thatīs basically an extranet where users will login and download some files.

The files are located outside the public_html, so they cant be linked directly. When the user asks for a file, Im doing like this:

code:
$data = file_get_contents(FILE_PATH.$fname);

header('Content-type: '.getFileExtension($fname));
header("Content-Disposition: attachment; filename=$fname");
echo $data;
Its not the best way, but it works. But now the client uploaded a 1.3 Gb file and then of course file_get_contents will fail for hitting the memory limit.

I cant raise the PHP memory limit anymore than I already did, so it can never qwork this way. What can I do then?

EDIT: as a temporary fix, Im copying the file to a folder inside public_html and then I redirect to its URL. It works but also leaves this copy were it can be downloaded by anyone, so its not a good solution of course.

Elias_Maluco fucked around with this message at 03:45 on Mar 25, 2011

cLin
Apr 21, 2003
lat3nt.net

Lumpy posted:

Searching "php permutate array" came up with lots of examples: http://www.google.com/search?sourceid=chrome&ie=UTF-8&q=php+permutate+an+array

Yea, I found some solutions, just figuring out how to filter it so it only accepts certain solutions.

for the solution by hsriat on http://bytes.com/topic/php/answers/776663-generating-permutations-combinations his would also show combinations such as The Red House and The Big House. I want to just get the combinations that don't have a word by itself..

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

cLin posted:

Yea, I found some solutions, just figuring out how to filter it so it only accepts certain solutions.

for the solution by hsriat on http://bytes.com/topic/php/answers/776663-generating-permutations-combinations his would also show combinations such as The Red House and The Big House. I want to just get the combinations that don't have a word by itself..

Ahhh... My bad, my reading comprehension failed me. I'm not sure what that type of problem is called, but I bet there is some clever, simple solution someone smarter than me will come up with, but I'll have a crack at it tomorrow.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

cLin posted:

How would I go about breaking a phrase down from something like "The Big Red House" into an array with the values
code:
The
Big
Red
House
The Big
Big Red
Red House
The Big Red
Big Red House
The Big Red House
Basically getting every possible phrase combination without reordering the original phrase. Would it be using a combination of a loop and explode()? I know permutations create every possible combination using a set of values...what would this be called so I can look it up.

So it seems to me that the way to approach this is: Substrings like this are parameterised by two things, the start point and the end point (with the end point necessarily being after the start point). So if you have two loops inside one another you should be able to do this using array_slice().

code:
function myFunction ($myString, $separator = ' ') {
    $myArray = strlen($separator) ?
               explode($separator, $myString) :
               str_split($myString);
    $length = count($myArray);
    $returnValue = array();
    for ($i = 1; $i <= $length; $i++) {
        for ($j = 0; $j <= $length - $i; $j++) {
            $returnValue[] = implode( $separator,
                                      array_slice($myArray, $j, $i)
                                      );
        }
    }
    return $returnValue;
}

var_dump(myFunction('The Big Red House'));

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I just realised that it would probably be nicer if it took arguments in the same order as implode() and explode(), but hey, what's a bit of inconsistency in argument order when you're using PHP.

KuruMonkey
Jul 23, 2004

Hammerite posted:

what's a bit of inconsistency in argument order when you're using PHP.

Inconsistency in argument order actually makes you consistent with the PHP core!

Edit:

A more fruitful contribution:

What you're looking for is a variation on a Power Set. I found this:
http://docstore.mik.ua/orelly/webprog/pcook/ch04_25.htm

Which requires a tweak (just reverse the order of the array merge) to get the elements in the same order as the input string.
Also; not a believer in creating some huge conglomeration of a function; splitting the string into an array and reconstituting the output into strings is a second, trivial issue; so "my" function just generates power sets of arrays:

php:
<?
    function array_power_set(Array $input) {
    
        $output = array(array());
        
        foreach($input as $element) {
            foreach($output as $combination) {
                array_push($output, array_merge($combination, array($element)));
            }
        }        
        
        return $output;
    
    }
    
    function dump(Array $input) {
        foreach($input as $combination) {
            echo implode(" ", $combination)."\n";
        }
    }


    $input = "The Big Red House";
    
    $words = explode(' ', $input);
    $output = array_power_set($words);
    
    dump($output);
?>
You would then want to filter on the length of the combination arrays, to remove the empty set etc.

Edit 2: some output would be nice, I guess?

code:

The
Big
The Big
Red
The Red
Big Red
The Big Red
House
The House
Big House
The Big House
Red House
The Red House
Big Red House
The Big Red House
There is an empty set there at the top.

KuruMonkey fucked around with this message at 11:26 on Mar 25, 2011

Pollyzoid
Nov 2, 2010

GRUUAGH you say?
I had a similar problem not too long ago, made the solution in Lua. I believe subset is the applicable term.

I'm not too experienced in PHP, I converted this from Lua. I tested it, it should work properly.

php:
<?
function array_subsets($input)
{
    $output = array();
    
    for($i=0; $i < sizeof($input); $i++)
    {
        for($j=0; $j < sizeof($input) - $i; $j++)
        {
            array_push($output, array_slice($input, $j, $i + 1));
        }
    }

    return $output;
}

$str = "The Big Red House";

$input = explode(' ', $str);

$sets = array_subsets($input);
?>
Returns an array of arrays, each containing a subset of the input table.

KuruMonkey's dump function prints this:
code:
The
Big
Red
House
The Big
Big Red
Red House
The Big Red
Big Red House
The Big Red House

Xenos
Jun 17, 2005

Elias_Maluco posted:

So I have this site thatīs basically an extranet where users will login and download some files.

The files are located outside the public_html, so they cant be linked directly. When the user asks for a file, Im doing like this:

code:
$data = file_get_contents(FILE_PATH.$fname);

header('Content-type: '.getFileExtension($fname));
header("Content-Disposition: attachment; filename=$fname");
echo $data;
Its not the best way, but it works. But now the client uploaded a 1.3 Gb file and then of course file_get_contents will fail for hitting the memory limit.

I cant raise the PHP memory limit anymore than I already did, so it can never qwork this way. What can I do then?

EDIT: as a temporary fix, Im copying the file to a folder inside public_html and then I redirect to its URL. It works but also leaves this copy were it can be downloaded by anyone, so its not a good solution of course.

Are you using Apache? If so, give mod_xsendfile a try. nginx and lighttpd have this as well.

If you can't use this module for whatever reason, you can always read the file in chunks and echo the chunks one at a time instead.

Xenos fucked around with this message at 14:28 on Mar 25, 2011

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
So yesterday I bucked up and started converting my app to objects, and I finally found a paradigm that's working.

1) A Registry to keep track of all the various managers
2) Managers to deal with I/O and other manipulation
3) Data objects with getters and setters

And I'm really enjoying how it's working so far. Now all I have to do is figure out how to separate the view from the controller and I'll be set, if it's even necessary.

I've made myself de-optimize some things. Before, when getting a particular entry from the database, I would join in two other tables and just put all the data in an array. Now, I get the main table, then send out calls to my manager classes to get objects for the other two things. Three queries instead of one, yes, but makes more sense/is cleaner in the code, and 3 simple selects instead of 1 isn't going to break me, not at the moment anyway.

Elias_Maluco
Aug 23, 2007
I need to sleep

Xenos posted:

Are you using Apache? If so, give mod_xsendfile a try. nginx and lighttpd have this as well.

If you can't use this module for whatever reason, you can always read the file in chunks and echo the chunks one at a time instead.

Yes, itīs a Apache, and thank you for the link, it seems perfect for what I need (I hope it works on my client server).

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Xenos posted:

If you can't use this module for whatever reason, you can always read the file in chunks and echo the chunks one at a time instead.

fpassthru is pretty much made for this.

cLin
Apr 21, 2003
lat3nt.net
KuruMonkey, Hammerite, Pollyzoid, Lumpy: Thanks for the help. I'm reading your functions which all seem to be somewhat similar (especially Hammerite and Pollyzoid) to understand it better.

KuruMonkey, your output still shows the initial problem I had which was strings like "The Big House" shouldn't have been outputted. At least, those are my results when I tested your function.

KuruMonkey
Jul 23, 2004

cLin posted:

KuruMonkey, your output still shows the initial problem I had which was strings like "The Big House" shouldn't have been outputted. At least, those are my results when I tested your function.

So you need only strings that are formed of the consecutive words in the string?
so; "The Big Red House" becomes:

The
Big
Red
House
The Big
Big Red
Red House
The Big Red
Big Red House
The Big Red House

Precisely?
1: I don't think there's a proper name for that, so I went for descriptive
2: this is now almost certainly exactly the same as the other versions, except I'm still working on array elements:

php:
<?
    function array_contiguous_subselections(Array $data) {
        $output = array();
        $limit = count($data);
        for($i=1; $i<=$limit; $i++) {
            for($j=0; $j<=($limit-$i); $j++) {
                $output[] = array_slice($data, $j, $i);
            }
        }
        return $output;
    }
?>
Can be dropped in as a direct replacement for my array_power_set function.
Its basically working along similar lines to shell-sort. Kind of a shell-select?

Edit: yep; pretty much identical to Pollyzoid's, except - consider a 50 word input array; How many times will Pollyzoid's code calulate the input array size? 1325 calls to sizeof()

I actually became very dull for a second, and ran a metric on the two functions, with a 1000 word input array (modifying each function to discard generated arrays to avoid running out of memory), and with 501500 calls to sizeof() vs 1 call to count(), the saving is 550ms out of a run time of ~18000ms on my desktop. Bearing in mind that the difference will have been amplified by my counter as well, not as bad as I thought. Nevertheless; count() before the loop is a worthwhile habit to form :)

KuruMonkey fucked around with this message at 17:19 on Mar 25, 2011

revmoo
May 25, 2006

#basta
In my chat app, I do a refresh every few seconds. I want to ping the db with the current unix time for that user/sessionid on each refresh.

Then, each refresh, the server will check to see if more than 5 mins have passed on each user's last ping, and if so, remove them from the userlist.

I feel like I have the code figured out but I'm lost on the SQL syntax coming from PHP because there's a mix of ' and " and ' and I'm not sure if anything needs to be escaped or what. I've tried a bunch of different combinations and none of them seem to end up with an actual db update as intended.

Here is the code. I've included the entire function just for context. This is just the function to add the ping time, nothing else:
code:
        function idleping() {
                $pingvar = microtime();
                $sesid = $_SESSION['id'];
                SQL::dbconnect();
                $pingquery = "UPDATE chat.userlist(ping) SET $pingvar WHERE chat.userlist(sessionid) = $sesid";
                mysql_query ($pingquery);
                SQL::dbclose();
                }

So, ping the db with updated unixtime for that userid each refresh. I can later track users who are 'gone' because their browsers have stopped updating.

I'm pretty sure my error is in the PHP/SQL syntax, but I'm lost as to what belongs in what ' " and what gets escaped and what the deal is. So educate my please? :)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

revmoo posted:

code:
        function idleping() {
                $pingvar = microtime();
                $sesid = $_SESSION['id'];
                SQL::dbconnect();
                $pingquery = "UPDATE chat.userlist(ping) SET $pingvar WHERE chat.userlist(sessionid) = $sesid";
                mysql_query ($pingquery);
                SQL::dbclose();
                }


UPDATE chat.userlist(ping) isn't valid syntax. I think you meant

UPDATE chat.userlist SET ping = $pingvar WHERE chat.userlist(sessionid) = $sesid

Also, I'm being paranoid, but I don't like seeing that $sesid = $_SESSION['id'] later used an the database query. If it were me I'd use $sesid = (int)$_SESSION['id'], but as I said I'm paranoid.

EDIT: Hang on a minute, I just paid proper attention to the WHERE clause and now I'm a bit lost. This: chat.userlist(sessionid) = $sesid isn't valid syntax either. What in that is the table name, and what is the column name? I'm going to take a guess that "chat" is the database name, "userlist" is the table name and "sessionid" is the column name, in which case you want

UPDATE chat.userlist SET ping = $pingvar WHERE chat.userlist.sessionid = $sesid

or even just (because there is only one table involved, you have no need to qualify any of the column names with the tables they came from)

UPDATE chat.userlist SET ping = $pingvar WHERE sessionid = $sesid

Hammerite fucked around with this message at 16:10 on Mar 26, 2011

revmoo
May 25, 2006

#basta
Here's what I ended up with, this works:
code:
function idleping() {
		$sesid = $_SESSION['id'];
		SQL::dbconnect();
		$pingvar = time();
		$pingquery = 'UPDATE chat.userlist SET ping="' . $pingvar . '" WHERE sessionid="' . $sesid . '"';
		mysql_query ($pingquery);
		SQL::dbclose();
	}

Hammerite posted:

Also, I'm being paranoid, but I don't like seeing that $sesid = $_SESSION['id'] later used an the database query. If it were me I'd use $sesid = (int)$_SESSION['id'], but as I said I'm paranoid.

You're absolutely right about this and I never would have considered it. This is a sneaky little security hole.

EDIT: By the way, here's the companion function to this one in case anyone is curious:
code:
function regcheck() {
		SQL::dbconnect();
		$xtime = time();
		$xtime -= 10;
		$checkarray =  mysql_query('SELECT * from chat.userlist WHERE ping <' . '"' . $xtime . '"');
		while ($tmpar = mysql_fetch_array($checkarray)) {
			$exited = '<span class="blue"> *** ' . $tmpar[1] . ' has left the room<br /></span>';
			mysql_query("INSERT INTO chat.chatlog(chat) VALUES('$exited')");
			$delq = 'DELETE FROM chat.userlist WHERE username = \'' . $tmpar[1] . '\'';
			mysql_query($delq);
		}
		SQL::dbclose();
	}
idleping(); is called on every browser hit to check and make sure a user is still live and on the site. regcheck() is called also every hit and if a user's browser has stopped pinging the site for 10secs, it removes them. the 10secs value will be a constant in config.php and I'll tie it into the refresh rate too. I'm sure there's a better way to do all the stuff I've done, I'm just playing around and trying to learn new things.

Here's the app: http://du.cx/dw

revmoo fucked around with this message at 04:27 on Mar 28, 2011

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION
I think we broke it.

Edit: nvm. You might wanna look at restricting the length of the name field however...

revmoo
May 25, 2006

#basta
Agreed. App seems to have handled it ok though :)

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

Golbez posted:

So yesterday I bucked up and started converting my app to objects, and I finally found a paradigm that's working.

1) A Registry to keep track of all the various managers
2) Managers to deal with I/O and other manipulation
3) Data objects with getters and setters

And I'm really enjoying how it's working so far. Now all I have to do is figure out how to separate the view from the controller and I'll be set, if it's even necessary.

I've made myself de-optimize some things. Before, when getting a particular entry from the database, I would join in two other tables and just put all the data in an array. Now, I get the main table, then send out calls to my manager classes to get objects for the other two things. Three queries instead of one, yes, but makes more sense/is cleaner in the code, and 3 simple selects instead of 1 isn't going to break me, not at the moment anyway.

Sounds like you are on the right track, but you don't necessarily need / want a single manager per table. Basically you need enough managers to satisfy the requirements of your application, but no more. The structure of your database should be encapsulated behind your manager without the rest of your app caring or knowing about individual tables.

Its like this. When you go to a restaurant and order a hamburger and fries, thats what you order, and thats what you get. In the kitchen it could be a cook that makes the burger, then someone puts the lettuce and bun on it, then your waiter brings it out. Or maybe its a small place and the waiter does all the cooking himself. None of that matters though, all that matters to you is that you tell your waiter what you want, and he brings it to you complete and ready to consume.

What you don't want to do is have to order a bun from one guy, a burger from another, guy, then lettuce from a third guy, then have to sit at your table and put your hamburger together. Then you might have a different restaurant where there are 6 separate people you need to talk to to get all the parts of your burger. In that case the staff needs to tell the customers what to do differently (i.e. recoding stuff that shouldn't need to change).

Lets say the requirements of your app are like this.

- You need to be able to retrieve, edit, and create orders.
- You need to be able to retrieve, edit, and create customers.
- Customers have sets of orders associated with them
- You need to be able to work with sets of orders based on the associated customer.

In this case you need methods like

code:
orderManager->Find(id);
orderManager->Save(order);
orderManager->Update(order);
orderManager->FindForCustomer(customer);
custManager->find(custId);
custManager->Save(customer);
custManager->Update(customer);
So an order might be spread across 4 different tables. But whatever is using your orderManager doesn't need or want to know that, it just needs an order. Later when you decide you need to refactor your db and add 2 more tables to it, you don't need to modify the code that uses the orderManager, you only modify the orderManager class itself to properly construct and return orders.

You don't have to code methods you don't need, add them later when you are going to actually use them.

Lets say you decide to modify your application a bit and have the data stored in XML files instead. In that case you just create a new orderManager that implements the same interface as your old orderManager, but does different stuff to build the orders (i.e. a waiter who prepares frozen burgers using a microwave, all you care is that you get the burger you ordered).

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine

Begby posted:

Sounds like you are on the right track, but you don't necessarily need / want a single manager per table. Basically you need enough managers to satisfy the requirements of your application, but no more. The structure of your database should be encapsulated behind your manager without the rest of your app caring or knowing about individual tables.
I'm not; I'm running it that, if a particular datatype is entirely subordinate to another, I'm including it in that manager. A status type is used only in a history entry, so the History Manager handles the status types (History entries are technically subordinate entirely to Employees, but they're complex enough to get their own manager)

And in cases where it's ambiguous where a function goes - like, "Does this employee have transactions", that could either be $TransactionManager->doesEmployeeHaveTransactions($employee) or $EmployeeManager->hasTransactions($employee). My rule has been, if the parameter is type X, it goes in XManager. In this case, the parameter is the employee, so it goes into EmployeeManager. Your orderManager->FindForCustomer(customer); down there goes against this, but in my case I'm more likely to have a generic search() function, so I'd have (for this example) orderManager->search(array('customer' => $customer)). For now, at least.

Also, a small semantic question: I often see methods like find() when it's identical to what I refer to as get(). I look at 'find' as a search, whereas with a 'get' I know exactly what I'm polling for. Why find over get?

Adbot
ADBOT LOVES YOU

Begby
Apr 7, 2005

Light saber? Check. Black boots? Check. Codpiece? Check. He's more machine than kid now.

Golbez posted:

And in cases where it's ambiguous where a function goes - like, "Does this employee have transactions", that could either be $TransactionManager->doesEmployeeHaveTransactions($employee) or $EmployeeManager->hasTransactions($employee). My rule has been, if the parameter is type X, it goes in XManager. In this case, the parameter is the employee, so it goes into EmployeeManager. Your orderManager->FindForCustomer(customer); down there goes against this, but in my case I'm more likely to have a generic search() function, so I'd have (for this example) orderManager->search(array('customer' => $customer)). For now, at least.

You should have the XManager retrieve and manipulate X. So a transactionManager should deal with checking on transactions for an employee as far as separation of concerns, otherwise you will be reading the same tables in a bunch of different managers all over and it will become a mess. One bad solution is to have your EmployeeManager use an instance of the TransactionManager, cuz' then what if your TransactionManager needs an instance of an EmployeeManager? Then you are kinda screwed.

In the ideal situation you would be coding against interfaces, so ordermanager->FindForCustomer() would take a parameter of ICustomer. To simplify it you could just give it a customerID as well, which is a very common solution. You might pass in ICustomer if ICustomer had an array of orders that you wanted to populate with orders from the order manager.


Golbez posted:

Also, a small semantic question: I often see methods like find() when it's identical to what I refer to as get(). I look at 'find' as a search, whereas with a 'get' I know exactly what I'm polling for. Why find over get?

Find or Get, whatever floats your boat.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply