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
Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Well, I notice no objections to my code on the grounds that it's missing anything crucial that leaves it insecure; just objections on the grounds that it's allegedly unnecessary. I intend to go ahead and phase it in in my code.

Adbot
ADBOT LOVES YOU

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Hammerite posted:

Well, I notice no objections to my code on the grounds that it's missing anything crucial that leaves it insecure; just objections on the grounds that it's allegedly unnecessary. I intend to go ahead and phase it in in my code.

Your code seems OK... I think people are just confused why you chose to reinvent the wheel is all.

Hammerite
Mar 9, 2007

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

Lumpy posted:

Your code seems OK... I think people are just confused why you chose to reinvent the wheel is all.

I don't have a good handle on what PDO "does". I have a good idea what my function does, though, as I wrote it myself!

I want to be able to do queries and get the results back in the form I want them (hence the three different return types). I also like that I can perform a query and get the results in an appropriate form with a single command. That's my idea of what it means to delegate a job I want doing to a pre-written function.

I don't suppose anyone here cares, but I made some changes. This is the version of that function that I've ended up using.

code:
function myerror($msg_not_test_mode,$msg_test_mode=null) {
    if ( TEST_MODE and !is_null($msg_test_mode) ) {
        trigger_error($msg_test_mode,E_USER_ERROR);
    } else {
        die($msg_not_test_mode);
    }
}

define('DBQUERY_WRITE',0);
define('DBQUERY_READ_RESULTSET',1);
define('DBQUERY_READ_SINGLEROW',2);
define('DBQUERY_READ_INTEGER',3);
define('DBQUERY_READ_INTEGER_TOLERANT_ZERO',4);
define('DBQUERY_READ_INTEGER_TOLERANT_NONE',5);
function dbquery($QueryType,$Query,$ParameterNames=null,$ParameterValues=null,$ShowInsteadOfIssue=false) {
    /*
        Example: To perform the query
            UPDATE `User` SET `IceCream` = 'Strawberry', `IQ` = 105 WHERE `UserID` = 1234
        you could use either of the following two commands:
            dbquery(DBQUERY_WRITE,
                    'UPDATE `User` SET `IceCream` = :icecream:, `IQ` = :iq: WHERE `UserID` = :userid:',
                    array('icecream'  ,'iq','userid'),
                    array('Strawberry',105 ,1234    )
                    )
            dbquery(DBQUERY_WRITE,
                    'UPDATE `User` SET `IceCream` = :icecream:, `IQ` = :iq: WHERE `UserID` = :userid:',
                    array('icecream' , 'Strawberry' ,
                          'iq'       , 105          ,
                          'userid'   , 1234
                          )
                    )
        Input must be checked beforehand for magic_quotes_gpc contamination.
        $ParameterNames and $ParameterValues should satisfy one of the following three criteria:
            - Both are null;
            - $ParameterNames is a string, and $ParameterValues is either a string, an integer, or null;
            - $ParameterNames is an array of strings, and $ParameterValues is an array with
              the same number of elements each of which is either a string, an integer, or null
              (note that the last element must be set, even if it is null);
            - $ParameterValues is null, and $ParameterNames is an array with an even number of
              elements, with all of the even-numbered elements (elements 0, 2, 4 etc.) being
              strings and all of the odd-numbered elements being either strings, integers or null
              (note that the last element must be set, even if it is null).
        $QueryType has no effect on the query itself; it controls return values as well as
        error messages displayed on failure. It should have one of the following values:
            DBQUERY_WRITE -> Write query (INSERT, UPDATE or DELETE); return mysqli result object
                             or 'NONE' if empty result set (should be 'NONE' or you are
                             doing it wrong, but this is not checked within the function)
            DBQUERY_READ_RESULTSET -> SELECT query; return mysqli result object or 'NONE' if empty result set
            DBQUERY_READ_SINGLEROW -> SELECT query, at most one row expected in resultset; return
                                      associative array or 'NONE' if empty result set
                                      (if there is more than one row in the result set
                                      then the second and subsequent rows are ignored)
            DBQUERY_READ_INTEGER -> SELECT query, resultset expected to be an integer scalar
                                    (e.g. 'SELECT COUNT(*) FROM TableName');
                                    return integer (error out if empty result set)
                                    (if there is more than one row in the result set
                                    then the second and subsequent rows are ignored;
                                    if there is more than one column in the result set
                                    then the second and subsequent columns are ignored)
            DBQUERY_READ_INTEGER_TOLERANT_ZERO -> As DBQUERY_READ_INTEGER but tolerates an empty
                                                  result set (returns integer 0)
            DBQUERY_READ_INTEGER_TOLERANT_NONE -> As DBQUERY_READ_INTEGER but tolerates an empty
                                                  result set (returns 'NONE')
    */
    global $cxn,$readerrormessage,$unexpectederrormessage,$writeerrormessage;
    if ( !is_int($QueryType) ) {
        myerror($unexpectederrormessage,'Query type should be an integer');
    } else if ( $QueryType == DBQUERY_WRITE ) {
        $ErrorMessage = $writeerrormessage;
    } else if ( $QueryType == DBQUERY_READ_RESULTSET or
                $QueryType == DBQUERY_READ_SINGLEROW or
                $QueryType == DBQUERY_READ_INTEGER or
                $QueryType == DBQUERY_READ_INTEGER_TOLERANT_ZERO or
                $QueryType == DBQUERY_READ_INTEGER_TOLERANT_NONE
                ) {
        $ErrorMessage = $readerrormessage;
    } else {
        myerror($unexpectederrormessage,'Unrecognised query type');
    }
    if ( is_string($ParameterNames) and
         ( is_string($ParameterValues) or
           is_int($ParameterValues) or
           is_null($ParameterValues)
           )
         ) {
        $ParameterNames  = array($ParameterNames);
        $ParameterValues = array($ParameterValues);
    }
    if ( is_null($ParameterValues) and
         is_array($ParameterNames) and
         count($ParameterNames) % 2 == 0
         ) {
        $ParameterNamesTemp = array();
        for ($i=0;2*$i<count($ParameterNames);$i++) {
            if ( !array_key_exists(2*$i,$ParameterNames) or
                 !array_key_exists(2*$i+1,$ParameterNames)
                 ) {
                // array_key_exists is used here because it distinguishes between an unset
                // array offset and an array offset that is set to null
                myerror($ErrorMessage,'Parameter array elements have nonstandard keys');
            }
            $ParameterNamesTemp[$i] = $ParameterNames[2*$i];
            $ParameterValues[$i]    = $ParameterNames[2*$i+1];
        }
        $ParameterNames = $ParameterNamesTemp;
    }
    if ( is_array($ParameterNames) and
         is_array($ParameterValues) and
         count($ParameterNames) == count($ParameterValues)
         ) {
        if ( count(array_unique($ParameterNames)) != count($ParameterNames) ) {
            myerror($ErrorMessage,'Duplicated parameter names');
        }
        $ParameterLocations = array();
        $OrderingArray      = array();
        for ($i=0;$i<count($ParameterNames);$i++) {
            if ( !array_key_exists($i,$ParameterNames) or
                 !array_key_exists($i,$ParameterValues) or
                 !is_string($ParameterNames[$i]) or
                 ( !is_string($ParameterValues[$i]) and
                   !is_int($ParameterValues[$i]) and
                   !is_null($ParameterValues[$i])
                   )
                 ) {
                // array_key_exists is used here because it distinguishes between an unset
                // array offset and an array offset that is set to null
                myerror($ErrorMessage,'Parameter array elements are the wrong types or have nonstandard keys');
            }
            $ParameterNames[$i] = ':'.$ParameterNames[$i].':';
            if ( is_string($ParameterValues[$i]) ) {
                $ParameterValues[$i] = '\''.mysqli_real_escape_string($cxn,$ParameterValues[$i]).'\'';
            }
            if ( is_null($ParameterValues[$i]) ) {
                $ParameterValues[$i] = 'NULL';
            }
            $SearchStartPoint = 0;
            while ( true ) {
                $CurrentParameterLocation = strpos(substr($Query,$SearchStartPoint),$ParameterNames[$i]);
                if ( $CurrentParameterLocation === false ) {
                    break;
                } else {
                    $ParameterLocations[]  = $SearchStartPoint + $CurrentParameterLocation;
                    $SearchStartPoint     += $CurrentParameterLocation + strlen($ParameterNames[$i]);
                    $OrderingArray[]       = $i;
                }
            }
        }
        if ( count($ParameterLocations) ) {
            array_multisort($ParameterLocations,$OrderingArray);
            $ExplodedQuery = explode(':!!:',str_replace($ParameterNames,':!!:',$Query));
            $Query = '';
            for ($i=0;$i<count($ParameterLocations);$i++) {
                $Query .= $ExplodedQuery[$i].
                          $ParameterValues[$OrderingArray[$i]];
            }
            $Query .= $ExplodedQuery[count($ParameterLocations)];
        }
    } else if ( !is_null($ParameterNames) or !is_null($ParameterValues) ) {
        myerror($ErrorMessage,'Parameter arguments are the wrong types');
    }
    if ( $ShowInsteadOfIssue ) { die('<pre>'.$Query.'</pre>'); }
    $QueryResult = mysqli_query($cxn,$Query);
    if ( !$QueryResult ) {
        myerror($ErrorMessage,'Query results in error message: "'.mysqli_error($cxn).'"');
    }
    if ( $QueryResult === true or mysqli_num_rows($QueryResult) == 0 ) {
        if ( $QueryType == DBQUERY_READ_INTEGER ) {
            myerror($ErrorMessage,'Expecting at least one row of output but found no rows');
        } else if ( $QueryType == DBQUERY_READ_INTEGER_TOLERANT_ZERO ) {
            $rtnvalue = 0;
        } else {
            $rtnvalue = 'NONE';
        }
    } else if ( $QueryType == DBQUERY_READ_INTEGER or
                $QueryType == DBQUERY_READ_INTEGER_TOLERANT_ZERO or
                $QueryType == DBQUERY_READ_INTEGER_TOLERANT_NONE
                ) {
        $rtnvalue = mysqli_fetch_row($QueryResult);
        $rtnvalue = (int)$rtnvalue[0];
    } else if ( $QueryType == DBQUERY_READ_SINGLEROW ) {
        $rtnvalue = mysqli_fetch_assoc($QueryResult);
    } else {
        $rtnvalue = $QueryResult;
    }
    while ( mysqli_more_results($cxn) ) { mysqli_next_result($cxn); }
    return $rtnvalue;
}

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
I really don't get it. No objects? Magic quotes escaping? .. mysqli?

Sure, writing your own DB handling stuff is a great learning experience, but I have to agree with everyone else on reinventing the wheel, there comes a point when you need to learn about the methods everyone else is advocating.

I'm not sure what you're doing with magic quotes, but surely that should be taken care of when you include the basics of whatever system you're using. Either switch them off or if thats not a possibility you could duplicate the request data into a "safe" array you can work with in your new code.

Fairly simple PDO abstraction lets you do poo poo like this:

php:
<?
// Anywhere. Preferrably on load and instanced internally or to/by a factory
$pdo = new MyPdoClass();
$pdo->Connect('server', 'schema', 'username', 'password');

// Anywhere else you like
// In this instance we make $pdo from an instance stored within MyPdoClass.
$pdo = new MyPdoClass();
$sql = "SELECT * FROM table WHERE value = ? AND something = ?"
$vars[] = "5";
$vars[] = $someParam;
$results = $pdo->Query_Table($sql, $vars);
$results = $pdo->Query_Cell($sql, $xs, $y, $vars);
$result = $pdo->Execute($sql, $vars);
?>
And if you want more control you can split the actions of Query_Table into further class methods, so you could get all nitty-gritty and specify data types, names and all sorts, or just use Query_Table and throw in your sql and vars and get an array back.

You say you don't know what PDO 'does', but in this instance its not doing much more than mysqli, it's just doing it better.

Hammerite
Mar 9, 2007

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

v1nce posted:

No objects?
This is absolutely a positive.

quote:

Magic quotes escaping? .. mysqli?
What about them?

quote:

there comes a point when you need to learn about the methods everyone else is advocating.
I see three possibilities:

(1) You are incorrect; there exists no such point.
(2) There exists such a point, but I have not yet reached it.
(3) There exists such a point, and I have reached or exceeded it, but I have not realised it.

You may feel that (3). I have not been convinced on the matter. In addition, whether the "you" of your statement refers to me personally or to a generic programmer is significant - there might be things that a career web developer would need to do that I, as a hobbyist, do not.

quote:

I'm not sure what you're doing with magic quotes, but surely that should be taken care of when you include the basics of whatever system you're using.
I agree.

quote:

Either switch them off or if thats not a possibility you could duplicate the request data into a "safe" array you can work with in your new code.
I could probably make sure that they are switched off, but I would prefer to maximise the portability of my scripts by writing them to work properly regardless of whether magic_quotes_gpc is on or off. I actually don't know whether they are on or off on my current host. I do know that my previous host had them switched on.

quote:

Fairly simple PDO abstraction lets you do poo poo like this:
php:
<?
...
$results = $pdo->Query_Table($sql, $vars);
$results = $pdo->Query_Cell($sql, $xs, $y, $vars);
$result = $pdo->Execute($sql, $vars);
?>
And if you want more control you can split the actions of Query_Table into further class methods, so you could get all nitty-gritty and specify data types, names and all sorts, or just use Query_Table and throw in your sql and vars and get an array back.
I did a search for "pdo Query Table" and "pdo Query Cell" and got no results, so I guess you intend these to be functions you would have come up with yourself. It's not clear to me what functionality you mean to imply that they have.

Working to provide the functionality you require as a matter of a simple function call is a great idea, indeed that's what I've done. If there is a difference here, you have not made me see it.

quote:

You say you don't know what PDO 'does', but in this instance its not doing much more than mysqli, it's just doing it better.
You have not convinced me of this.

duz
Jul 11, 2005

Come on Ilhan, lets go bag us a shitpost


Ah, good ol' NIH syndrome.

Hammerite
Mar 9, 2007

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

duz posted:

Ah, good ol' NIH syndrome.

If someone prefers a different way of doing things to the way advocated by prevailing opinion on an internet forum, they must be suffering from a syndrome? That's a dumb thing to imply.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Hammerite posted:

If someone prefers a different way of doing things to the way advocated by prevailing opinion on an internet forum, they must be suffering from a syndrome? That's a dumb thing to imply.

Everybody here has probably been guilty of doing exactly what you are doing here at some point. Bottom line is, the less code you write, the less code you have to maintain. Let a whole bunch of other people handle API design and QA for database abstraction, it's just one less thing you have to worry about now. Also, when another developer comes along to help with your project, they (hopefully) already know PDO, and they don't have to learn Yet Another Layer.

Use existing peer reviewed code whenever possible, then you can focus to actually developing your product instead of problems that have been solved 100x over!

Even if nobody is going to look at your code now, it's important to develop good habits early on. That way you don't have to deal with transitioning how to write a "solo" project and how you work on something with a few more people.

fletcher fucked around with this message at 23:32 on Apr 11, 2010

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
Fletcher has it absolutely spot on, and duz makes a very good point about NIH.
It's not just because you're doing it a "different" way, it's because you're doing something everyone else has done before - not grasped a solution and worked your way around it.

I can speak from experience having written my own framework (my own learning experience), which is time I would have better spent learning a pre-existing system. This is what I mean by the need to learn methods other people advocate, even if it's just to confirm that your method is the right one.

My example code was purely an example of what you can do with some simple work in classes, seeing as you shot down fletchers previous example, so you won't find those functions anywhere online as they denote abstraction of PDO into simpler interfaces.

I'm sure I've been down this path with you before, but is there any reason for your not using objects for things like this? They usually provide far superior facilities when doing stuff like this.

DaTroof
Nov 16, 2000

CC LIMERICK CONTEST GRAND CHAMPION
There once was a poster named Troof
Who was getting quite long in the toof

Hammerite posted:

If someone prefers a different way of doing things to the way advocated by prevailing opinion on an internet forum, they must be suffering from a syndrome? That's a dumb thing to imply.

Are you saying that advocacy of tried and tested libraries like PDO is unique to this forum? That's a downright ignorant thing to imply.

If you don't understand why you've been accused of NIH syndrome, refer back to this:

quote:

I don't have a good handle on what PDO "does". I have a good idea what my function does, though, as I wrote it myself!

It's totally your prerogative to write a custom solution for a problem that's already been solved. Just don't expect a lot of pats on the back for it. If you ever need to ask why a query isn't working, you'll need to post the function code along with it, and the first question you'll get back from anyone who's never seen it is "Why aren't you using a common library?"

Hanpan
Dec 5, 2004

so I'm developing some software which requires the user to be authenticated. In the past, I've generally logged the user, set a session and checked the session exists at the start of each page load.

I was wondering what else I could do to make my software a little bit more secure?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I don't want to drag this thread off on a tangent again, so I'll stop contributing to this derail I started. Thanks to the posters who take an interest in helping me develop (even if I'm not necessarily always receptive to it). It's not my intention to be rude. I did get an answer to the question I originally posted, so I got what I wanted.

gwar3k1
Jan 10, 2005

Someday soon

Hanpan posted:

so I'm developing some software which requires the user to be authenticated. In the past, I've generally logged the user, set a session and checked the session exists at the start of each page load.

I was wondering what else I could do to make my software a little bit more secure?

One you will have commonly seen is a fingerprint hash. Salt and hash a string and save it in the session. Add this hash to all of your links and compare the hash from a url to the one stored in session. If they're different, destroy the session and ask for credentials.

Another method is to get the user agent string and compare that to the first instance of getting the user agent (ie at login). If the user agent has changed, destroy the session etc..

Mr Viper
Jun 21, 2005

Derezzed...
My website, hosted with GoDaddy (yes I know, no I can't do anything about it), was recently switched over from Windows hosting to Linux hosting. All of the sudden, NONE of my mail scripts work. I even installed PEAR, and their Mail() and Mail_Mime() functions aren't working either.

For what it's worth, this is all the script is

php:
<?
mail("admin@findyourfirsthome.com", "Subject", "Body of the email");
?>
Yeah, that simple. Just to make sure I didn't mess it up, I tried the exact same file on my windows server (with 1and1), and it works fine. I've done some messing with .htaccess and php5.ini since the server was changed, but I don't think it would have anything to do with that at all.

Is there some voodoo reason why mail() doesn't work with Linux?



edit: Here is a link to show what I'm doing. You can see that running the script returns "false" or whatever, and it fails.

Mr Viper fucked around with this message at 02:03 on Apr 13, 2010

IT Guy
Jan 12, 2010

You people drink like you don't want to live!

Mr Viper posted:

My website, hosted with GoDaddy (yes I know, no I can't do anything about it)

Wait, I'm not up to speed on why this is a bad thing.

Can someone inform me?

What about domain name registration, is that alright with GoDaddy? If not what's good?

DaTroof
Nov 16, 2000

CC LIMERICK CONTEST GRAND CHAMPION
There once was a poster named Troof
Who was getting quite long in the toof

IT Guy posted:

Wait, I'm not up to speed on why this is a bad thing.

Can someone inform me?

What about domain name registration, is that alright with GoDaddy? If not what's good?

In my experience, GoDaddy tends to use underpowered and overloaded servers running out-of-date software for shared hosting. Sometimes their server configurations require exceptional code for things that "just work" on most other hosts, which is annoying.

Their domain name registration, however, is top-notch.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

IT Guy posted:

Wait, I'm not up to speed on why this is a bad thing.

Can someone inform me?

What about domain name registration, is that alright with GoDaddy? If not what's good?

I've had a dedicated server for a few years from them and I've registered all my domains through them, never really had an issue. I think the main complaint about GoDaddy is they are pretty aggressive with selling poo poo. You won't be able to talk to them on the phone without them trying to get you to renew poo poo in advance, and you can't buy a domain through their website without them trying to nickel and dime you every step of the way. I'm guessing this is why they are the most popular registrar though. Gotta make money, right?

That being said, the prices seem fine and the service has been reliable, which is really all I care about.

As far as the mail() issue, does a phpInfo() show a path to sendmail? Or maybe contact GoDaddy?

edit: actually, google "godaddy php mail function", seems lots of others have this issue as well

fletcher fucked around with this message at 02:25 on Apr 13, 2010

Mr Viper
Jun 21, 2005

Derezzed...

fletcher posted:

As far as the mail() issue, does a phpInfo() show a path to sendmail? Or maybe contact GoDaddy?

http://www.findyourfirsthome.com/phpinfo.php

sendmail_from: no value
sendmail_path: /usr/sbin/sendmail -t -i


Is that "sendmail_from" blank line a problem?

IT Guy
Jan 12, 2010

You people drink like you don't want to live!

fletcher posted:

I've had a dedicated server for a few years from them and I've registered all my domains through them, never really had an issue. I think the main complaint about GoDaddy is they are pretty aggressive with selling poo poo. You won't be able to talk to them on the phone without them trying to get you to renew poo poo in advance, and you can't buy a domain through their website without them trying to nickel and dime you every step of the way. I'm guessing this is why they are the most popular registrar though. Gotta make money, right?

I guess that's true, every year when I goto renew my several domain names, I have to read everything very loving carefully as to not accidentally click continue or submit and subscribe to a service I didn't want.

DaTroof
Nov 16, 2000

CC LIMERICK CONTEST GRAND CHAMPION
There once was a poster named Troof
Who was getting quite long in the toof

fletcher posted:

I've had a dedicated server for a few years from them and I've registered all my domains through them, never really had an issue. I think the main complaint about GoDaddy is they are pretty aggressive with selling poo poo. You won't be able to talk to them on the phone without them trying to get you to renew poo poo in advance, and you can't buy a domain through their website without them trying to nickel and dime you every step of the way. I'm guessing this is why they are the most popular registrar though. Gotta make money, right?

That being said, the prices seem fine and the service has been reliable, which is really all I care about.

As far as the mail() issue, does a phpInfo() show a path to sendmail? Or maybe contact GoDaddy?

Their dedicated servers are somewhat better than their shared hosting, although there are still several companies I'd prefer to lease from than GoDaddy.

As for the mail problem, last I remember, GoDaddy requires all automated mail to use a particular mail server, which their shared servers aren't configured to use from the PHP mail() function. You should be able to configure a mail library that supports SMTP, like PHPMailer or SwiftMail, to use their required configuration. Search their FAQ. It's in there somewhere.

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Mr Viper posted:

http://www.findyourfirsthome.com/phpinfo.php

sendmail_from: no value
sendmail_path: /usr/sbin/sendmail -t -i


Is that "sendmail_from" blank line a problem?

I don't think so...mine has no value and it works fine.

Reading through the google results it sounds like they disable the mail() function so spammers don't use it. Can you use something else with your own smtp server?

Mr Viper
Jun 21, 2005

Derezzed...
See, I would underastand if the mail() thing didn't work with GoDaddy, I just don't understand why it would only work on windows servers. I can't find any documentation anywhere that explains this.

First Time Caller
Nov 1, 2004

I can assure you that mail() works just fine on non-windows machines

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

First Time Caller posted:

I can assure you that mail() works just fine on non-windows machines

I think he means why it works on THEIR windows servers, but not in THEIR non-windows servers, not in general.

Mr Viper
Jun 21, 2005

Derezzed...
Thanks everyone for the help regarding my issue. Turns out it was GoDaddy's fuckup THE ENTIRE TIME. They just didn't believe me. :)

I love being a programmer

epswing
Nov 4, 2003

Soiled Meat

Mr Viper posted:

it was GoDaddy's fuckup THE ENTIRE TIME

Elaborate please!

Mr Viper
Jun 21, 2005

Derezzed...

epswing posted:

Elaborate please!

Yesterday morning I woke up to a phone call from my boss, telling me the "email clients" function was broken on our site. This code was working perfectly fine a couple days prior, last time I checked it. Two days ago, I changed from Windows to Linux servers, and I assumed at some point during the transfer, something got screwed up.

I called GoDaddy and explained the problem, showing them the same code example I showed you guys. They said they'd ask the upper administrators, and I got a response back that they didn't know what was wrong. Over the next 2 or 3 calls, I had them tell me there was some file somewhere I must have overwritten, or my code was bad. I searched every drat file, googled a thousand different wordings of "php mail not working", and nothing fixed it.

Finally, I called again this morning, and had a new rep send a new report to the upper administrators. Half an hour later, it was fixed. It was never anything wrong with my code, it was ALWAYS something wrong with their servers, and for God knows what reason, they couldn't figure it out.

keep it down up there!
Jun 22, 2006

How's it goin' eh?

Not sure if this is best posted here or the SQL thread, but here goes.

I'm creating a facebook game using CodeIgniter as my framework. I want to have a page where a user can see which of their friends play the game and see their in game information.

I created the following code, but it seems to take a while to execute and sometimes the page times out.
I added some comments to help explain it since not everyone knows the facebook API and how CodeIgniter works.

php:
<?
      // This returns an array of all the facebook friends
                  $data['friends'] = $this->facebook->api_client->friends_get();

      //I then loop through that array and call the facebook function to create my own array ($friends) of people using my app

                      $friends = array();
                      foreach ($data['friends'] as $row)
                      {
                          if($this->facebook->api_client->users_isAppUser($row))
                          {
                              $friends[] = $row;
                          }
                      }

      //This here is how the framework im using does SQL.  Essentially Im creating a giant where clause.

                      $this->db->where_in('user_id', $friends);
                      $this->db->order_by("user_id", "desc");
                      $data['party'] = $this->db->get('users');

?>
Since Facebook friends can change constantly, I figured it was better to let them always handle that since I can call it anytime. So I check to see which of the users friends has the app, and then create a giant where based on that. But as I said it seems to run very poorly.

Is there any way to make this more efficient? Or is it my host causing the issues? I'm on crappy shared hosting while I develop this, but plan to get something beefier when I launch it.


EDIT
I did some testing in PHPMyAdmin and executing the query on its own resolves super fast. So I'm guessing now it's an issue with the framework. :(

keep it down up there! fucked around with this message at 18:35 on Apr 14, 2010

Yay
Aug 4, 2007
Given the query itself runs reasonably fast, and codeigniter isn't exactly slow (for a framework. Its inevitably slower than just including a couple of files yourself.), I'd imagine that the facebook API itself is the problem. Having not worked with the Facebook API in any language, I'm assuming its REST or XMLRPC? In which case, aren't you doing N HTTP requests to test if the user 'isAppUser'?

(Edit: to clarify, if you are doing an HTTP request for every friend, that's potentially quite a lot; and even if facebook is fast at returning the data (I'd imagine it is), your shared host may not be quick at it)

keep it down up there!
Jun 22, 2006

How's it goin' eh?

That's what I'm figuring as well now. Not sure of any way to work around it though. I think checking all of a users friends against my DB for ones that exist would be slower. It's possible for someone to have over a thousand friends, so that's one crazy SQL call.

Begby
Apr 7, 2005

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

BUGS OF SPRING posted:

That's what I'm figuring as well now. Not sure of any way to work around it though. I think checking all of a users friends against my DB for ones that exist would be slower. It's possible for someone to have over a thousand friends, so that's one crazy SQL call.

Assuming you could do this in a limited number of queries, and your database was properly optimized for the query, querying your database for 1000 friends will be magnitudes faster than calling a web api 1000 times in a row.

Can't you just modify your "where in" clause to include all of the facebook friends regardless of whether or not they are an app user? That would just skip over the ones that didn't exist in your db.

Sebbe
Feb 29, 2004

As I recall, sending Facebook queries was insanely slow last time I used the Facebook API, so that is indeed most likely the problem.

By the looks of it, you'll want to use Friends.getAppUsers instead. (friends_getAppUsers in the PHP API, I believe.)

That way you do one API call instead of hundreds.

keep it down up there!
Jun 22, 2006

How's it goin' eh?

Sebbe posted:

As I recall, sending Facebook queries was insanely slow last time I used the Facebook API, so that is indeed most likely the problem.

By the looks of it, you'll want to use Friends.getAppUsers instead. (friends_getAppUsers in the PHP API, I believe.)

That way you do one API call instead of hundreds.

This worked. The reason I didn't know this function existed is it's not in the dev console, but is on the wiki. Kinda stupid.
Thanks a million for pointing it out.

keep it down up there! fucked around with this message at 20:31 on Apr 14, 2010

Thirteenth Step
Mar 3, 2004

I've created a basic change password script for a logged in user.

code:
<form method="post" action="">
Username: <?php echo $_SESSION['username']; ?>
Password:
<input type="text" name="password" id="password" /><br />
New Password:
<input type="text" name="newpassword" id="newpassword" /><br />
Confirm New Password:
<input type="text" name="confirmnewpassword" />
<input type="submit" name="submit">
</form>
php:
<?
 

session_start(); 
// define connection to DB
mysql_connect("localhost","root","");
mysql_select_db("db");

// post form information
@$username = $_SESSION['username']; 
@$password = $_POST['password']; 
@$newpassword = $_POST['newpassword']; 
@$confirmnewpassword = $_POST['confirmnewpassword']; 

$result = mysql_query("SELECT password FROM staff WHERE username='$username'"); 

if(!$result)  
{  
echo "The username you entered does not exist<br>";  
}  
else  
if($password != mysql_result($result, 0))  
{  
echo "You entered an incorrect password<br>";  
}  
else
if($newpassword=$confirmnewpassword){ 
    mysql_query("UPDATE staff SET password='$newpassword' where username='$username'");   
    echo "Congratulations You have successfully changed your password<br>";  
    } 
else 
{  
echo "The new password and confirm new password fields must be the same<br>";  
}   
?>
When I enter different passwords into the 'new password' and 'confirm new password' boxes, the users password gets changed to whatever was in the 'confirm new password' box rather then rejecting it and producing an error message.

Can anyone see why it's doing this?!

IT Guy
Jan 12, 2010

You people drink like you don't want to live!

Thirteenth Step posted:

I've created a basic change password script for a logged in user.

code:
<form method="post" action="">
Username: <?php echo $_SESSION['username']; ?>
Password:
<input type="text" name="password" id="password" /><br />
New Password:
<input type="text" name="newpassword" id="newpassword" /><br />
Confirm New Password:
<input type="text" name="confirmnewpassword" />
<input type="submit" name="submit">
</form>
php:
<?
 

session_start(); 
// define connection to DB
mysql_connect("localhost","root","");
mysql_select_db("db");

// post form information
@$username = $_SESSION['username']; 
@$password = $_POST['password']; 
@$newpassword = $_POST['newpassword']; 
@$confirmnewpassword = $_POST['confirmnewpassword']; 

$result = mysql_query("SELECT password FROM staff WHERE username='$username'"); 

if(!$result)  
{  
echo "The username you entered does not exist<br>";  
}  
else  
if($password != mysql_result($result, 0))  
{  
echo "You entered an incorrect password<br>";  
}  
else
if($newpassword=$confirmnewpassword){ 
    mysql_query("UPDATE staff SET password='$newpassword' where username='$username'");   
    echo "Congratulations You have successfully changed your password<br>";  
    } 
else 
{  
echo "The new password and confirm new password fields must be the same<br>";  
}   
?>
When I enter different passwords into the 'new password' and 'confirm new password' boxes, the users password gets changed to whatever was in the 'confirm new password' box rather then rejecting it and producing an error message.

Can anyone see why it's doing this?!
if($newpassword=$confirmnewpassword){

Assigning the variable. Use ==

Thirteenth Step
Mar 3, 2004

IT Guy posted:

if($newpassword=$confirmnewpassword){

Assigning the variable. Use ==

No way...! :gonk: Thanks.

Just as another small follow-up; with my user register forms and this one too, some echo's such as "password incorrect" and "The new password and confirm new password fields must be the same" are showing even before the form has been filled out, how can I stop this?

Acer Pilot
Feb 17, 2007
put the 'the' in therapist

:dukedog:

You can try moving the form processor to another file and change your script to link to it. eg.

<form method="post" action="check.php">

Your problem right now is that you're checking the form even if nothing has been entered yet.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I have spent an hour or so getting acquainted with basic object oriented stuff. Motivation is, I have a script to do a particular job and the code is currently quite long and ugly; I suspect it might be an appropriate place to apply OO to simplify things. (No, it has nothing in particular to do with databases.)

I have the following code which works as I expect it to. My question is possibly a bit of a nebulous one and I won't be surprised if it gets no replies. It is, does this code in your opinion have good style? Are there any bad practices in it?

Ignore that the classes are defined in-file rather than included from somewhere. The code is intentionally self-contained. Ignore also the roundabout method of getting coordinate properties used in some places in the final echo statement; this was for the sake of experimentation.

php:
<?php

class point {

    private $x,$y;

    function __construct ($initial_x$initial_y) {
        $this -> = (int)$initial_x;
        $this -> = (int)$initial_y;
    }

    public function set_x ($new_x) { $this -> = (int)$new_x; }
    public function set_y ($new_y) { $this -> = (int)$new_y; }

    public function get_x () { return $this -> x; }
    public function get_y () { return $this -> y; }

}

class rectangle {

    private $left,$right,$top,$bottom;

    function __construct ($x1$x2$y1$y2) {
        $x1 = (int)$x1;
        $x2 = (int)$x2;
        $y1 = (int)$y1;
        $y2 = (int)$y2;
        if ( $x1 $x2 ) {
            $this -> left  $x1;
            $this -> right $x2;
        } else {
            $this -> left  $x2;
            $this -> right $x1;
        }
        if ( $y1 $y2 ) {
            $this -> top    $y1;
            $this -> bottom $y2;
        } else {
            $this -> top    $y2;
            $this -> bottom $y1;
        }
    }

    public function set_left   ($new_left)   { $this -> left   = (int)$new_left;   }
    public function set_right  ($new_right)  { $this -> right  = (int)$new_right;  }
    public function set_top    ($new_top)    { $this -> top    = (int)$new_top;    }
    public function set_bottom ($new_bottom) { $this -> bottom = (int)$new_bottom; }

    public function get_left   () { return $this -> left;   }
    public function get_right  () { return $this -> right;  }
    public function get_top    () { return $this -> top;    }
    public function get_bottom () { return $this -> bottom; }

    public function get_topleft     () { return new point($this -> left,  $this -> top   ); }
    public function get_topright    () { return new point($this -> right$this -> top   ); }
    public function get_bottomleft  () { return new point($this -> left,  $this -> bottom); }
    public function get_bottomright () { return new point($this -> right$this -> bottom); }

    public function set_width ($new_width) {
        $new_width = (int)$new_width;
        if ( $new_width ) {
            trigger_error('Negative rectangle width supplied',E_USER_ERROR);
        }
        $this -> right $this -> left $new_width;
    }
    public function set_height ($new_height) {
        $new_height = (int)$new_height;
        if ( $new_height ) {
            trigger_error('Negative rectangle height supplied',E_USER_ERROR);
        }
        $this -> bottom $this -> top $new_height;
    }

    public function get_width  () { return $this -> right  $this -> left; }
    public function get_height () { return $this -> bottom $this -> top;  }

}

function bounding_rectangle() {
    $num_things func_num_args();
    if ( $num_things == and is_array(func_get_arg(0)) ) {
        $things_array func_get_arg(0);
        $num_things count($things_array);
    } else {
        for ($i=0;$i<$num_things;$i++) {
            $things_array[$i] = func_get_arg($i);
        }
    }
    if ( $num_things ) {
        for ($i=0;$i<$num_things;$i++) {
            if ( is_a($things_array[$i],'rectangle') ) {
                $x1[$i] = $things_array[$i] -> get_left();
                $x2[$i] = $things_array[$i] -> get_right();
                $y1[$i] = $things_array[$i] -> get_top();
                $y2[$i] = $things_array[$i] -> get_bottom();
            } else if ( is_a($things_array[$i],'point') ) {
                $x1[$i] = $things_array[$i] -> get_x();
                $x2[$i] = $things_array[$i] -> get_x();
                $y1[$i] = $things_array[$i] -> get_y();
                $y2[$i] = $things_array[$i] -> get_y();
            } else {
                trigger_error('Each argument to bounding_rectangle() should be either a rectangle or a point',
                              E_USER_ERROR
                              );
            }
        }
        $x1 min($x1);
        $x2 max($x2);
        $y1 min($y1);
        $y2 max($y2);
    } else {
        $x1 0;
        $x2 0;
        $y1 0;
        $y2 0;
    }
    return new rectangle($x1,$x2,$y1,$y2);
}

$myrectangle = array ( new rectangle(72,60,50,200),
                       new rectangle(32,40,100,200),
                       new rectangle(32,43,-50,14),
                       new point(20,5)
                       );

$myrectangle[1] -> set_height(156);

$myrectangle bounding_rectangle($myrectangle);

// Here I have used two different ways of obtaining the coordinates of my rectangle's vertices.
// I have used the direct method provided by class rectangle in places; in other places I have
// taken the more roundabout route of obtaining the point object and then using the method
// provided by class point to find the coordinates of said point.

echo 'The top-left of my rectangle is at ('.
     $myrectangle -> get_topleft() -> get_x().', '.$myrectangle -> get_topleft() -> get_y().
     ').<br>The top-right of my rectangle is at ('.
     $myrectangle -> get_topright() -> get_x().', '.$myrectangle -> get_topright() -> get_y().
     ').<br>The bottom-left of my rectangle is at ('.
     $myrectangle -> get_left().', '.$myrectangle -> get_bottom().
     ').<br>The bottom-right of my rectangle is at ('.
     $myrectangle -> get_right().', '.$myrectangle -> get_bottom().
     ').<br> My rectangle has width '.$myrectangle -> get_width().
     ' and height '.$myrectangle -> get_height().'.';

?>

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Hammerite posted:

I have spent an hour or so getting acquainted with basic object oriented stuff. Motivation is, I have a script to do a particular job and the code is currently quite long and ugly; I suspect it might be an appropriate place to apply OO to simplify things. (No, it has nothing in particular to do with databases.)

I have the following code which works as I expect it to. My question is possibly a bit of a nebulous one and I won't be surprised if it gets no replies. It is, does this code in your opinion have good style? Are there any bad practices in it?

Ignore that the classes are defined in-file rather than included from somewhere. The code is intentionally self-contained. Ignore also the roundabout method of getting coordinate properties used in some places in the final echo statement; this was for the sake of experimentation.



It seems a bit... much.

php:
<?
class Point
{
  public $x;
  public $y;

  function __construct( $x, $y )
  {
    $this->x = $x;
    $this->y = $y;
  }
}

class Rectangle
{
  private $origin;  // a Point
  private $height; // height
  private $width;  // width

  function __construct( $origin, $height=0, $width=0 )
  {
    $this->origin = $origin;
    $this->height = $height;
    $this->width = $width;
  }

  public static function initWithTwoPoints( $topLeft, $bottomRight )
  {
    $me = new self();
    $this->origin = $topLeft;
    $this->height = $topLeft->y - $bottomRight->y // but account for bottom right being negative =)
    $this->width = $topRight->x  - $topLeft->x // account for negatives blah blah
    return $me;
  }
  // make other 'constructors' like the one above.
  // maybe 'initWithFourCoordinates( $x1, $y1, $x2, $y2 )' or whatever
  // call these "bonus" constructors like:  $myRect = Rectangle::initWthTwoPoints( $p1, $p2 );

  public function moveRectToPoint( $newOrigin ) //$newOrigin is a Point
  {
    $this->origin = $newOrigin;
  }
  
  public function moveRectTo( $x, $y)
  {
    $this->origin->x = $x;
    $this->origin->y = $y;
  }

  public function moveRectBy( $deltaX=0, $deltaY=0 )
  {
    $this->origin->x  += $deltaX;
    $this->origin->y  += $deltaY;
  }


  public function changeSize( $newH, $newW )
  {
    $this->height = $newH;
    $this->width = $newW;
  }

  public function getOrigin()
  {
    return $this->origin;
  }
  public function getHeight()
  {
    return $this->height;
  }
  public function getWidth()
  {
    return $this->width;
  }


  // other fun methods
  public function getArea()
  {
    return $this->height * $this->width;
  }
  // blah blah 
}
?>
You may not want to define too many getters... it's neat to have a 'getTopLeft' 'getTopRight', etc. but unless you constantly need those things, you may find it a bit overkill, as it's dead simple to figure those things out elsewhere. There's no hard rule about that or anything, but try to make individual objects / classes do as little as possilbe, as it's easier to write, easier to maintain, and whatnot. For dead simple stuff, you don't need to make setters and getters ( like Point, yes it's 'proper' to have them, but why write four methods for two properties )

Lumpy fucked around with this message at 00:47 on Apr 16, 2010

Adbot
ADBOT LOVES YOU

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Hammerite posted:

I have literally never seen someone put spaces around arrow operators before. Don't be a special snowflake. Your point class is 16 lines of code for a pair of ints. You do not need four setters and eight getters for something that can be represented as two points. You're using is_a in bounding_rectangle in a situation other than pattern matching in a functional language. Don't do that.

Plorkyeran fucked around with this message at 04:55 on Apr 16, 2010

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