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
Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING

McGlockenshire posted:

You also forgot to tell us what you mean when you say that it "doesn't work."

It returns array(0) {}.

Jabor posted:

Do the tables have the same columns in the same order? Union wants to combine things which have the same structure, which would explain why combining a single column from each table works, but trying to do it to everything fails.

That... would be it. Damnit. So I'll have to do a query for the unique ID of each row that finds a LIKE, and then return the table name and do sub-queries for each one grabbing *...

I did not know union couldn't work that way, but I guess I should have anticipated problems. Thanks for your help.

Adbot
ADBOT LOVES YOU

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled
I'm trying to migrate a huge codebase from PHP 5.1 to 5.4. What documentation might help me? The PHP changelogs are more of a "we fixed these bugs" list but what I really need is a "these are the significant changes and depreciated functions" list.

teethgrinder
Oct 9, 2002

DaTroof posted:

Zym has a nice template for phpDocumentor that's similar to Yii's design: http://zymengine.com/dev/news/30-phpdoc-extjs-converter-template
Thanks. We ended up actually going with Swagger which is amazing for our purposes. We're working in JSON, and it has a nifty Sandbox/try-it-out feature for the web service requests.

-JS-
Jun 1, 2004

teethgrinder posted:

Thanks. We ended up actually going with Swagger which is amazing for our purposes. We're working in JSON, and it has a nifty Sandbox/try-it-out feature for the web service requests.

Swagger is awesome - it's built into the latest version of Restler which makes building an API whilst someone else is building an app to consume it much easier.

teethgrinder
Oct 9, 2002

Boy I wish I knew about that ... oh two months ago. Live & learn :)

McGlockenshire
Dec 16, 2005

GOLLOCKS!

Cock Democracy posted:

I'm trying to migrate a huge codebase from PHP 5.1 to 5.4. What documentation might help me? The PHP changelogs are more of a "we fixed these bugs" list but what I really need is a "these are the significant changes and depreciated functions" list.

They only started throwing deprecation warnings in 5.3. The PHP manual has a set of appendices including the change lists between major versions.

If the code running on 5.1 was actually designed for 5.1 and used best then-best practices, you should actually be OK. Most of the stupid crap that breaks nowadays has to do with holdovers from 4.x practices.

Cock Democracy
Jan 1, 2003

Now that is the finest piece of chilean sea bass I have ever smelled

McGlockenshire posted:

They only started throwing deprecation warnings in 5.3. The PHP manual has a set of appendices including the change lists between major versions.

If the code running on 5.1 was actually designed for 5.1 and used best then-best practices, you should actually be OK. Most of the stupid crap that breaks nowadays has to do with holdovers from 4.x practices.
Thanks. Most of the code was written in 2009 so it's not extremely ancient but it does seem to have some PHP 4 influences. It definitely has PHP mixed with HTML. It doesn't use PDO or any parameterized queries. I wonder why they picked 5.1 anyway since 5.2 would have been available to them.

musclecoder
Oct 23, 2006

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

Cock Democracy posted:

Thanks. Most of the code was written in 2009 so it's not extremely ancient but it does seem to have some PHP 4 influences. It definitely has PHP mixed with HTML. It doesn't use PDO or any parameterized queries. I wonder why they picked 5.1 anyway since 5.2 would have been available to them.

If I had to guess it was running on a RedHat machine which had 5.1.6 installed by default forever.

stoops
Jun 11, 2001
I have a variable that spits out an array:

code:
array(
	(int) 0 => array(
		'name' => 'file12_04.fit',
		'fullpath' => '/web/file12_04.fit',
	),
	(int) 1 => array(
		'name' => 'file13_04.fit',
		'fullpath' => '/web/file13_04.fit',
	),
	(int) 2 => array(
		'name' => 'file13_03.fit',
		'fullpath' => '/web/file13_03.fit',
	),

The _O4 or _03 is a version number.

I'd like to run some code that will look at the "name" in the array and only give me the files that have an "_03" in it.

I wasn't sure how to go about it. Any help or point in the right direction is appreciated. Thanks.

Leavy
Feb 15, 2003

rufus

stoops posted:

I have a variable that spits out an array:

The _O4 or _03 is a version number.

I'd like to run some code that will look at the "name" in the array and only give me the files that have an "_03" in it.

I wasn't sure how to go about it. Any help or point in the right direction is appreciated. Thanks.

This should do ya.

php:
<?
$array = array(
    (int) 0 => array(
        'name' => 'file12_04.fit',
        'fullpath' => '/web/file12_04.fit',
    ),
    (int) 1 => array(
        'name' => 'file13_04.fit',
        'fullpath' => '/web/file13_04.fit',
    ),
    (int) 2 => array(
        'name' => 'file13_03.fit',
        'fullpath' => '/web/file13_03.fit',
    )
);
    
foreach($array as $value)
{
    if (strrpos($value['name'], '_03', -7)) {
        //Name has _03 at the end of the string
    }
}

?>
Check out the documentation on strrpos if you want to see what that guy is doing.

stoops
Jun 11, 2001

Leavy posted:

This should do ya.

php:
<?
$array = array(
    (int) 0 => array(
        'name' => 'file12_04.fit',
        'fullpath' => '/web/file12_04.fit',
    ),
    (int) 1 => array(
        'name' => 'file13_04.fit',
        'fullpath' => '/web/file13_04.fit',
    ),
    (int) 2 => array(
        'name' => 'file13_03.fit',
        'fullpath' => '/web/file13_03.fit',
    )
);
    
foreach($array as $value)
{
    if (strrpos($value['name'], '_03', -7)) {
        //Name has _03 at the end of the string
    }
}

?>
Check out the documentation on strrpos if you want to see what that guy is doing.

Thanks Leavy, i modified a few things to make it work, but sttrpos was a step in the right direction, so thanks.

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker
array_filter is more awesomer. :colbert:

php:
<?
$array = array(
     0 => array(
        'name' => 'file12_04.fit',
        'fullpath' => '/web/file12_04.fit',
    ),
     1 => array(
        'name' => 'file13_04.fit',
        'fullpath' => '/web/file13_04.fit',
    ),
     2 => array(
        'name' => 'file13_03.fit',
        'fullpath' => '/web/file13_03.fit',
    )
);

$version_03_files = array_filter($array, function($fit){
    return preg_match('/.*_03.fit$/i', $fit['name']);
});

?>

jiggerypokery
Feb 1, 2012

...But I could hardly wait six months with a red hot jape like that under me belt.

I have a background developing C++ applications with Xcode. I have just been offered a job developing PHP for a small web software consultancy and I need to learn PHP before I start. Xcode doesn't support PHP so I was wondering about what IDE's people prefer and why. I have VMware with a copy of windows 8 installed on my macbook (and could install linux on it too obviously) so I am not limited to mac IDE's.

I've shot an email to the company to find out what they use but thought I would throw an ask here to see what people think.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS
I use an *AMP stack and Sublime Text 2 for most of my development. ST2 has a linting plugin available that can show you obvious errors like missing semicolons or unclosed quotes and braces.

If I need to do anything more in-depth, like debugging the deep internals of an ajax function, I'll use NetBeans and xDebug.

McGlockenshire
Dec 16, 2005

GOLLOCKS!
PHPStorm is considered by many to be the best PHP IDE.

Komodo used to be pretty good back in the day as well.

Regardless, Blinkz0rz is totally right about xdebug being pretty much mandatory for debugging purposes. Do note that because of the scripted nature of PHP, a lot of devs forego actual debugging in favor of good old print_r/var_dump.

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

McGlockenshire posted:

Do note that because of the scripted nature of PHP, a lot of devs forego actual debugging in favor of good old print_r/var_dump.

Which, to add on a bit more, makes a lot of sense when you're talking about writing code that causes an action at some point in the page load cycle and is quite a bit easier to do.

For outputting nicely formatted variables, I recommend using '<pre>' . print_r($var, true) . '</pre>'

If you're debugging post-load functionality, especially ones that require some kind of data submitted with the request (say for example, using nonces to verify form submissions) you'll need to be able to set breakpoints in the code to examine the action.

CainFortea
Oct 15, 2004


This is more of a general question. Basically I want to be able to make a script that checks a code that was in the URL. It is checking the code in the URL against a MySQL table or checks if it's a valid number against an algorithm. If it passes, it lets the user download a file.

My question is more this; what is that kind of opperation refered to? I don't even know what to look up when trying to find if there's a premade package I can find that does this stuff.

Edit: Sorry, reworded it because it wasn't clear.

Calyn
Sep 3, 2011

CainFortea posted:

This is more of a general question. Basically I want to be able to make a script that checks a code that was in the URL. It is checking the code in the URL against a MySQL table or checks if it's a valid number against an algorithm. If it passes, it lets the user download a file.

My question is more this; what is that kind of opperation refered to? I don't even know what to look up when trying to find if there's a premade package I can find that does this stuff.

Edit: Sorry, reworded it because it wasn't clear.

You mean like in .../showthread.php?threadid=2802621 - you want to compare threadid to some stored value?

$_GET: http://www.php.net/manual/en/reserved.variables.get.php

php:
<?
echo htmlspecialchars($_GET["threadid"]);
?>
However while you are at it, you should look into "GET vs POST" and be aware that you will need to sanitize that data before doing anything with it, especially before using it in a database query, or you have a huge security issue.

McGlockenshire
Dec 16, 2005

GOLLOCKS!

Calyn posted:

be aware that you will need to sanitize that data before doing anything with it, especially before using it in a database query, or you have a huge security issue.

Nitpick: You're accidentally combining validation, sanitization, database value escaping and output escaping in that statement. These are four totally different things that you should not group together.

All input should be validated against expected values. If you want an integer, make sure it's an integer. If you're processing a dropdown menu, make sure that the value submitted is in the list of things that should have been in the dropdown to begin with.

Some input should be sanitized. If you want an integer, actively cast it to an integer. If you have a free-form text input field that shouldn't have HTML in it, make sure it's free of HTML contamination by either neutralizing or removing the tags and entities.

Whenever you insert data into a database, you should use a prepared statement with placeholders. If you're stuck in the dark ages and aren't using a database library with real (or even emulated) prepared statements, you'll need to properly escape and quote that input. Every single time.

Whenever you emit any data, regardless of whether it's from the database or from the user, you need to make sure that it is free of possible contamination by escaping based on what you're doing. If you're writing JSON, use json_encode. If you're echoing a thing that should be free of HTML and might not already have been escaped, use htmlspecialchars.

And so on. Combining these four totally different things is why PHP has such a bad reputation, and is demonstrated even in the very title of this thread...

CainFortea
Oct 15, 2004


Calyn posted:

You mean like in .../showthread.php?threadid=2802621 - you want to compare threadid to some stored value?

$_GET: http://www.php.net/manual/en/reserved.variables.get.php

php:
<?
echo htmlspecialchars($_GET["threadid"]);
?>
However while you are at it, you should look into "GET vs POST" and be aware that you will need to sanitize that data before doing anything with it, especially before using it in a database query, or you have a huge security issue.

My question was more, if i'm looking for scripts already written or packages people are selling, what do I search for? Example, if i'm looking for java code to parse text from an input box, I know to search for parsing with java.

Though if I do have to write it from scratch that does help. Thank you.

Aniki
Mar 21, 2001

Wouldn't fit...
Edit 2: I resolved this issue. I should have thought through this problem more before posting it. I ended up choosing to use a for loop to index the elements of the arrays, which got rid of the issue of indexes of the check boxes being off. Once I solved that issue, it's easy to handle the data and check to see which elements are set.

I'm experimenting with a form where a user checks rows and then it returns the data as arrays. If all of the boxes are checked, then it works and the keys match for the different field arrays as below:

quote:

SELECT ALL
Array
(
[0] => on
[1] => on
[2] => on
)


TestData
Array
(
[0] => Test1
[1] => Test2
[2] => Test3
)

However, if one of the boxes is unchecked, then it does not return an element for the unchecked box, but it still returns elements for the corresponding fields even if I leave them blank. In this case, I checked the 1st and 3rd boxes of the form, but left the 2nd box unchecked and got the following result:

quote:

SELECT ALL
Array
(
[0] => on
[1] => on
)


TestData
Array
(
[0] => Test1
[1] => Test2
[2] => Test3
)

I was expecting to see $arrSelectAll[1] be off or even just null, and $arrSelectAll[2] to be on, but instead the results for $arrSelectAll[2] are stored in $arrSelectAll[1], which makes the results out of sync with the $arrTestData array. I could just manually assign indexes to each checkbox (e.g. name="select[1]"), but it seems like there should be a way for me to do this without predefined indexes.

This is the form that I created:

code:
    <form action="jQueryCheckAll.php" method="post" enctype="multipart/form-data">
        <table>
            <tr>
                <td><input type="checkbox" id="select_all"/></td>
                <td>&nbsp;<td/>
            </tr>
            <tr>
                <td><input type="checkbox" name="select[]"/></td>
                <td><input type="text" name="testData[]" />
            </tr>
            <tr>
                <td><input type="checkbox" name="select[]"/></td>
                <td><input type="text" name="testData[]"/>
            </tr>
            <tr>
                <td><input type="checkbox" name="select[]"/></td>
                <td><input type="text" name="testData[]"/>
            </tr>
        </table>
        <input type="hidden" name="postback" value="1" />
        <input type="submit" name="submit" value="submit" />
    </form>
And this is the PHP that I wrote to process the posted data:

php:
<?
if (isset($_POST['postback']) === true) :
    $postback =  trim($_POST['postback']);
    
    if ($postback == 1) :
        $arrSelectAll = $_POST['select'];
        $arrTestData = $_POST['testData'];
        
        echo "SELECT ALL\n";
        echo "<Pre>";
        print_r($arrSelectAll);
        echo "</Pre>";
        echo "<br /><br />";
        echo "TestData\n";
        echo "<Pre>";
        print_r($arrTestData);
        echo "</Pre>";
        echo "<br /><br />";
        
        foreach( $arrSelectAll as $key => $n ) :
          print $n. " >>>> " . $arrTestData[$key] . "<br \><br />";
        endforeach;
    endif;
endif;
?>
I'm not sure why it isn't returning some sort of result for unchecked boxes, so do you guys have any recommendations on how I can approach this differently?

Thank you in advanced for your assistance.

Edit: It looks like the common solution is to pass a hidden variable that mirrors the check box and then compare the hidden variable to the checkbox. However that doesn't resolve the issue of the keys not matching. I'll try reading up on this more, but any suggestions would be appreciated. Would I be better off using jQuery or something to get the state of the check boxes?

Aniki fucked around with this message at 00:48 on Mar 27, 2013

Quote-Unquote
Oct 22, 2002



Does anyone here know much about sending mail through a local Exchange server from PHP?
I'm having an issue where any mail I send (either using mail() or the PEAR mail package) to any external address via our Exchange 2003 server results in an NDR saying that I do not have permission to send to this recipient. I can send to the address just fine from Outlook/OWA, using the same sender account as I'm using in PEAR mail with SMTP authentication working fine, but nothing from PHP will go.

I think it's something to do with our spam filter, which is managed by a third party, but they're insisting that there's nothing being blocked there so I'm trying to exhaust possibilities this end. I'm fairly positive it's related to them, because we never had a single problem until literally two minutes after we switched over to them when a scheduled task was supposed to send an email.

I'm not too knowledgable about Exchange in general, but I did find this in the logs (smtproutes is the spam filter they provide, I've replaced my name and my company's name), which looks to me like it's the spam filter rejecting the mail.

code:
2013-03-26 15:13:04 208.70.89.157 OutboundConnectionResponse SMTPSVC1 CHW-EX01 - 25 - - 220+cal3-mh481.smtproutes.com+kath-5.0.3+ESMTP+Ready 5969 SMTP - - - -
 2013-03-26 15:13:04 208.70.89.157 OutboundConnectionCommand SMTPSVC1 CHW-EX01 - 25 EHLO - mail.mycompany.com 5969 SMTP - - - -
 2013-03-26 15:13:05 208.70.89.157 OutboundConnectionResponse SMTPSVC1 CHW-EX01 - 25 - - 250-cal3-mh481.smtproutes.com+says+Hello+[my company's ip address] 7281 SMTP - - - -
 2013-03-26 15:13:05 208.70.89.157 OutboundConnectionCommand SMTPSVC1 CHW-EX01 - 25 MAIL - FROM:<myname@mail.mycompany.com> 7281 SMTP - - - -
 2013-03-26 15:13:07 208.70.89.157 OutboundConnectionResponse SMTPSVC1 CHW-EX01 - 25 - - 250+2.1.0+Sender+Accepted:+myname@mail.mycompany.com 8562 SMTP - - - -
 2013-03-26 15:13:07 208.70.89.157 OutboundConnectionCommand SMTPSVC1 CHW-EX01 - 25 RCPT - TO:<myname@gmail.com> 8562 SMTP - - - -
 2013-03-26 15:13:08 208.70.89.157 OutboundConnectionResponse SMTPSVC1 CHW-EX01 - 25 - - 550+5.7.1+Recipient+rejected+(R1) 9844 SMTP - - - -
And here's the PHP script (NB: it sends to internal addresses just fine, just nothing outbound)
code:
 require("mail.php");
 $from = "myname@mycompany.com>";
 $to = "myname@gmail.com>";
 $subject = "Test";
 $body = "Testing\r\nTesting";
 
 $host = "myexchangeserver.mylocaldomain.local";
 $username = "myusername";
 $password = "mypassword
 
 $headers = array ('From' => $from,'To' => $to,'Subject' => $subject);
 $smtp = Mail::factory('smtp',array ('host' => $host,'auth' => true,'username' => $username,'password' => $password));
 
 $mail = $smtp->send($to, $headers, $body);
 
 if (PEAR::isError($mail)) {
   echo($mail->getMessage());
  } else {
   echo("Message sent!");
}

The Gripper
Sep 14, 2004
i am winner

Quote-Unquote posted:

Does anyone here know much about sending mail through a local Exchange server from PHP?
I'm having an issue where any mail I send (either using mail() or the PEAR mail package) to any external address via our Exchange 2003 server results in an NDR saying that I do not have permission to send to this recipient. I can send to the address just fine from Outlook/OWA, using the same sender account as I'm using in PEAR mail with SMTP authentication working fine, but nothing from PHP will go.
It could be that the user you are using doesn't have Send As permissions, though I honestly don't know know the specific circumstances where that is necessary (whether it's needed only when sending as a different address than the account has listed, or if it also applies to sending when not a member of the domain explicitly).

Quote-Unquote
Oct 22, 2002



The Gripper posted:

It could be that the user you are using doesn't have Send As permissions, though I honestly don't know know the specific circumstances where that is necessary (whether it's needed only when sending as a different address than the account has listed, or if it also applies to sending when not a member of the domain explicitly).

The user is me, on my AD account, using my exchange mailbox :)

Edit: managed to resolve the issue. It was the spam filter, despite the third-party company denying it. Simply removed them from the Smart Host setting in the virtual SMTP server on Exchange and mail is getting through fine now.

Quote-Unquote fucked around with this message at 16:04 on Mar 27, 2013

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker

Better/easier solution:

code:
<input type="checkbox" id="select_all"/>
<input type="checkbox" name="select[1]"/>
<input type="text" name="testData[]" /><br class="clear">
<input type="checkbox" name="select[2]"/>
<input type="text" name="testData[]"/><br class="clear">
<input type="checkbox" name="select[3]"/>
<input type="text" name="testData[]"/><br class="clear">
(although do realise the indexes are now strings instead of ints but because of type juggling it won't matter much)

karms fucked around with this message at 11:02 on Apr 4, 2013

stoops
Jun 11, 2001
I have an array of numbers:

1-10.

Does php have a function where if I submit a number to this array, it will give me the number closest to what I submitted?

for array (1-10)
example 1: If I submit, 7, it will give me 6.
example 2: If I submit 21, it will give me 10.

for array (56, 48, 45, 30, 23)
example 3: If I submit 41, it would give me 30.

The array of numbers aren't always going to be consecutive, but they will be in descending order.

Any point to the right direction is appreciated.

Amarkov
Jun 21, 2010
Your statement doesn't agree with your examples. Why doesn't example 1 give 7, which is closer? Why doesn't example 3 give 45?

(PHP doesn't have a native function to do any of the things you might mean, but if you know how to iterate through an array it's pretty easy to do on your own.)

v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.

KARMA! posted:

Better/easier solution:

I concur with this. Don't ever use the anonymous form name array feature (name="blah[]") unless you're happy for your data to come back as a jumble. If you want a form field to be locked to a particular ID, use that ID in the forms array key (name="blah[1234]").

I see a lot of systems where people don't get form arrays, so they put name="mything_124_17_opt" which is just stupid. As your fields look like they're supposed to be related, maybe try this:

code:
<input type="checkbox" id="select_all"/>
<input type="checkbox" name="data[1][enabled]"/>
<input type="text" name="data[1][value]" /><br class="clear">
<input type="checkbox" name="data[2][enabled]"/>
<input type="text" name="data[2][value]"/><br class="clear">
<input type="checkbox" name="data[3][enabled]"/>
<input type="text" name="data[3][value]"/><br class="clear">
Throw that over to PHP for a good time. In this example, only the 2nd checkbox was toggled:

code:
Array
(
    [data] => Array
        (
            [1] => Array
                (
                    [value] => textEntry1
                )

            [2] => Array
                (
                    [enabled] => on
                    [value] => textEntry2
                )

            [3] => Array
                (
                    [value] => textEntry3
                )
        )
)
Just because I can't not do this, here's my version of your PHP. Sorry for making GBS threads on your coding standards.

php:
<?
if (isset($_REQUEST['postback']))
{
    $postback = trim($_REQUEST['postback']);
    
    if ($postback == '1')
    {
        $data = $_REQUEST['data'];
        
        echo "Fied Data\n";
        echo '<pre>';
        print_r($data);
        echo '</pre>';
        echo '<br /><br />';
        
        foreach( $data as $option )
        {
            $checked = ( isset($option['enabled']) ? 'checked' : 'unchecked');
            echo "{$checked} >>>> {$option['value']} <br \><br />";
        }
    }
}
?>
Brackets because it's easier to read
Removed the usage of one "print" and made it an "echo" for conformity
A ternary operator for checked/unchecked because it's a simple comparison on isset() that we want to convert to something useful (text).
$_REQUEST because it's a combination of $_GET $_POST and $_COOKIE, and it's easier just to not trust one user-submitted variable, and it's easier to debug because you can just stuff vars in the URL (GET).
String comparison on the if($postback) just because it's a little more rigid and less likely to go funny because of PHPs type casting magic.


stoops posted:

Does php have a function where if I submit a number to this array, it will give me the number closest to what I submitted?

As Amarkov said, no. I Googled for "php numeric array search, closest match" and found this, though:
http://stackoverflow.com/questions/5464919/php-nearest-value-from-an-array

v1nce fucked around with this message at 03:39 on Apr 4, 2013

karms
Jan 22, 2006

by Nyc_Tattoo
Yam Slacker

Amarkov posted:

Your statement doesn't agree with your examples. Why doesn't example 1 give 7, which is closer? Why doesn't example 3 give 45?

(PHP doesn't have a native function to do any of the things you might mean, but if you know how to iterate through an array it's pretty easy to do on your own.)

It's rounded down.

php:
<?
$array = sort(array(1,3,78,3,5,7,0,2));

$n = 6;
$answer = null;
foreach($array as $number)
{
    if($number > $n) break;
    $answer = $number;
}

// $answer == 6
?>

karms fucked around with this message at 11:08 on Apr 4, 2013

stoops
Jun 11, 2001

v1nce posted:

As Amarkov said, no. I Googled for "php numeric array search, closest match" and found this, though:
http://stackoverflow.com/questions/5464919/php-nearest-value-from-an-array

KARMA! posted:

It's rounded down.

Thanks guys. Karma, I couldn't get your code to work. It was probably just me, since I'm not that great at php.

Vince, I ended up using a code piece from that link, so thanks.

Fluue
Jan 2, 2008
I've been assigned a project in one of my Web Development classes and I have a question regarding passing a PDO object to classes.

I'm unable to use a framework, so I'm developing simple classes for user management and other functions for my project. I haven't been able to find a definite answer regarding passing PDO to my classes upon construction so that I can query without creating new PDO instances for every class, though.

Is this considered "correct" for what I'm trying to accomplish?

php:
<?php


class User
{
    private $pdo;

    //use this like so:
    // $user = new User($db);
    function __construct(PDO $pdo){
        $this->pdo $pdo;
    }

    public function login($username$password){

        $login $this->pdo->prepare("SELECT * FROM users WHERE username= :user");
        $login->bindValue(':user'$usernamePDO::PARAM_STR);
        $login->execute();

        $result $login->fetch(PDO::FETCH_ASSOC);

        $password //do some kind of hashing here

        if($result['password'] == $password){
            return TRUE;
        }
    }
}


v1nce
Sep 19, 2004

Plant your brassicas in may and cover them in mulch.
There's certainly nothing explicitly wrong with that approach, but you're putting a lot of low-level stuff in your class which is going to lock you in hard and fast to PDO. Imagine you write 500 queries for your app and then discover your deployment environment will only run basic SQL calls; you'd need to go through and substitute PDO all over the shop, which isn't fun.

It's also going to complicate things if you're passing your PDO variable with the constructor, meaning you likely need a Factory class to initialize anything, or you're passing $pdo round like a hot potato in your controller/dispatcher, which is fine until you want to initialize it where PDO isn't available in scope, and then you'd need to make it a global which causes the floor to open up and you to be swallowed up by a anger of a thousand coders.

Most frameworks will use a class to store the DB instance itself (your PDO object), and you'd make a call to your model like "$this->query($sql)" which is passed onto that DB instance. Some frameworks use Factory classes to pass on the DB instance, others just use a static class. If that all went over your head, no problems, here's an example;

php:
<?
/**
 * User model
 */
class User extends Model
{
    /**
     * Check the $username and $password credentials.
     * @param $username     Users username
     * @param $password     Users password
     * @return bool         True if correct credentials
     */
    public function login($username, $password)
    {
        // Query and vars
        $sql = "
            SELECT
                *
            FROM
                users
            WHERE
                username = :user
        ";
        $vars[] = array(':user', $username, PDO::PARAM_STR);

        // Get result
        $result = $this->preparedQuery($sql, $vars);

        // Do check
        return ($result['password'] == $password);
    }
}


/**
 * Model abstract; abstracting our database source
 */
abstract class Model
{
    /**
     * @var PDO     Database instance
     */
    protected $db;

    /**
     * Initialize DB source for this model
     */
    public function __construct()
    {
        $db = Datasource::getSource();
    }

    /**
     * @param $sql              Prepared statement
     * @param $values           Data for prepared statement
     * @param int $fetchMethod  PDO Fetch method
     * @return mixed            SQL result
     */
    public function preparedQuery($sql, $values, $fetchMethod=PDO::FETCH_ASSOC)
    {
        // Initialize query
        $query = $this->db->prepare($sql);

        // Add variables
        if (sizeof($values))
        {
            foreach ($values as $value)
            {
                // 0 = bind name
                // 1 = variable
                // 2 = type
                $query->bindValue($value[0], $value[1], $value[2]);
            }
        }

        // Run query
        $query->execute();

        // Return data
        return $query->fetch( $fetchMethod );
    }
}


/**
 * Stores all the database sources
 */
class Datasource
{
    protected static $sources;

    /**
     * Fetch the data source from storage
     * @param   string  $name   Data source name
    * @return   PDO             Data source
     */
    public static function getSource( $name='default' )
    {
        // Source must exist in config
        if(!isset($sources[$name]))
        {
            trigger_error("The specified source '{$name}' does not exist.", E_USER_ERROR);
        }

        // Load DB where possible
        if (!isset($sources[$name]['object']))
        {
            $sources['object'] = new PDO( $sources[$name]['dsn'], $sources[$name]['username'], $sources[$name]['password']  );
        }

        // Return DB instance
        return $sources[$name];
    }


    /**
     * Load Config for data sources
     * @param
     */
    public static function loadConfig( $config )
    {
        // Save the config passed in.
        self::$sources = $config;
    }

}


// Load the DB config
Datasource::loadConfig( array(
    'default'=>array(
        'username'=>'user',
        'password'=>'pass',
        'dsn'=>'mysql:dbname=myDatabase;host=localhost'
    )
));

// Check users login
$user = new User;
$login = $user->login('vince', '1234');

// Result
echo ($login == true ? 'Logged in' : 'Invalid username or password');
?>
I haven't tested this as I'm writing it in my lunch break, but hopefully it's educational. A few notes:
I've massively overcomplicated this by make the DataSource class, but that's there because it would allow us to connect to multiple data sources. This is never important until you need it, and can cause you to rewrite a lot of code if you have to fudge it in later.
This arrangement still doesn't completely free you from PDO, as we're still constructing a list of variables ($vars) in login(), and using stuff like PDO::PARAM_STR. You could get rid of this and use some checks on the variables to work out the type, and you could remove the need for :user: by using "?" all over the place, but this is a nice compromise. You get the power of the prepared statement names and datatypes, and if you need to escape PDO you just can ignore those variables.

No doubt someone will have a reason not to do it entirely this way, but an important point is to give yourself more power and an escape route if you need to get away from a particular library like PDO, without having to rewrite everything.

Finally, punch whoever is the reason you're not allowed to use a framework, because you're basically writing your own as a result.

Oh and, you could just use the "$db = Datasource::getSource();" bit in your model's constructor, and the Datasource class. To answer your original question.

DholmbladRU
May 4, 2006
Ive decided to take upon a project at work that will serve as a tool for my small team. It is essentially going to be a collection of code snippets and other text that will be stored in a central location and allow users to perform robust searches on this data. This is going to be more for fun, and to learn php again. The initial problem I am encountering is deciding how to store this 'text'. As this will be code from a number of different languages it can be stored as unformatted, and upon retrieval I will figure out how to properly indent this. The question I have is how should I store this code or text, it will be short snippets probably single methods or classes 20-300 lines. Maybe store the text in files on the 'server' and store pointers to these files in a database along with keywords that are parsed out of the text upon entry. I could see problems with this in the future if the database has issues and all the pointers are lost. However I think that performing robust searches over 1000 .txt files containing code could take some time, so I dont know if that is an option.

Hammerite
Mar 9, 2007

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

DholmbladRU posted:

Ive decided to take upon a project at work that will serve as a tool for my small team. It is essentially going to be a collection of code snippets and other text that will be stored in a central location and allow users to perform robust searches on this data. This is going to be more for fun, and to learn php again. The initial problem I am encountering is deciding how to store this 'text'. As this will be code from a number of different languages it can be stored as unformatted, and upon retrieval I will figure out how to properly indent this. The question I have is how should I store this code or text, it will be short snippets probably single methods or classes 20-300 lines. Maybe store the text in files on the 'server' and store pointers to these files in a database along with keywords that are parsed out of the text upon entry. I could see problems with this in the future if the database has issues and all the pointers are lost. However I think that performing robust searches over 1000 .txt files containing code could take some time, so I dont know if that is an option.

Store the text snippets in the database. There is no need to faff around storing little text files separately from the database, it's not like you're talking about large blobs or something.

DholmbladRU
May 4, 2006

Hammerite posted:

Store the text snippets in the database. There is no need to faff around storing little text files separately from the database, it's not like you're talking about large blobs or something.

thats what I figured. thanks for the info

SimonNotGarfunkel
Jan 28, 2011
Don't forget there'll be plenty of parsers out there which will do all the code formatting for you.

DarkLotus
Sep 30, 2001

Lithium Hosting
Personal, Reseller & VPS Hosting
30-day no risk Free Trial &
90-days Money Back Guarantee!

SimonNotGarfunkel posted:

Don't forget there'll be plenty of parsers out there which will do all the code formatting for you.

I've been dreaming up a side project that will need to parse different languages (css, html, php, python, java, etc...). Instead of reinventing the wheel, do you have any examples of these parsers you speak of?

Saoshyant
Oct 26, 2010

:hmmorks: :orks:


This being the year 2013 and most frameworks having dropped PHP 4 long ago and, in the process, rewritten themselves, I'm wondering what framework is usually better to handle web projects outside huge applications. CodeIgniter has been my go-to framework for a while since its version 2, but I have always been curious how modern Kohana compares to it -- any article comparing them seems to be from 2009, which isn't helpful.

Then, there's always been Yii, which I considered overkill in most situations, but I have never been 100% sure if this assessment is correct.

SimonNotGarfunkel
Jan 28, 2011
Having been pretty impressed with CI as a newcomer to frameworks in the last few months, and then being overwhelmed with Symfony2 I've finally landed on Laravel 4 Beta and really love it.

The community support is excellent and eloquent ORM is fantastic.

You should check out the screencasts to get a feel of how it hangs together.

The first official release is expected in 6 months.

Adbot
ADBOT LOVES YOU

McGlockenshire
Dec 16, 2005

GOLLOCKS!
Look at Symfony 2 first, then Zend Framework 2. Symfony is regarded as well-engineered, while ZF2 is regarded as over-engineered.

Avoid frameworks with a reliance on static methods (Laravel, Yii), and frameworks that use ActiveRecord as their ORM of choice (Yii, Cake, CI). ActiveRecord is an anti-pattern that violates the SRP, and reliance on static methods makes automated testing very difficult.

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