How do you avoid hard coding SQL statements in PHP?
-
Is there a good way to prevent hard coding of insert/update sql statements in PHP? I'm writing a data-driven PHP application. In several cases, there is a large SQL table, and different users are responsible for submitting different fractions of the data (i.e. Alice submits 3 of a row's fields, Bob submits 4 other ones). There are also cases where the web application modifies all the fields in a row. I've been hard coding the INSERT and UPDATE statements for each form handler which feels like bad design (especially if new database fields are added in the future). Does anyone have experience with this type of problem? Any good solutions?
-
Answer:
If you have an array of fields and an array of values, you can use sprintf to dynamically insert them into the SQL without too much trouble. It's less work than learning and using a whole framework, but you do have to be a little careful about pre-escaping your data. As you're walking along your conditions, just append stuff to the $fields and $values arrays until you have everything you're ready to stick everything into the database. Making $values another array deep and doing a little more string massaging can you get into multi-row insert land, too.$fields = array("name","dob","email");$values = array("'soma lkzx'", "12-12-1900","'[email protected]'");if($is_bob) { array_push($fields, "height"); array_push($values, 145);}$sql = sprintf("INSERT INTO tablename (%s) VALUES (%s)", implode($fields, ","), implode($values,","))I am not a PHP coder by any means and this is just back-of-the-napkin code. You could also take advantage of key-value pairs in associative arrays instead of having separate $fields and $values.
secret.osha at Ask.Metafilter.Com Visit the source
Other answers
You're looking for http://www.devshed.com/c/a/PHP/Database-Abstraction-With-PHP/. http://www.symfony-project.org is a PHP framework that makes this kind of thing very simple.
odinsdream
Depending on the SQL server you are using, Stored Procedures is the way to go for that problem. Here's a quick link i googled that gives the overview for PHP and MS SQL : http://www.sitepoint.com/article/php-microsoft-sql-server/. Basically, you write the inserts / updates in the SQL engine, and then call them almost like a function from PHP. If you need advice on the PHP - MySQL link, mefimail me, but it's very similar to the MSSQL.
frwagon
Another way is to use an Object Relational Model like http://www.doctrine-project.org/, or a framework that includes a database abstraction layer like the aforementioned Symfony or http://framework.zend.com. I think PHPIgniter and CakePHP also include these features, but my experience is mostly with Symfony and Zend Framework because they have more advanced features that only come with PHP5.
SpecialK
soma lkzx: That's actually a cool little trick there. I'll pass it along to my PHP friend who never took to frameworks who still codes his PHP apps in Dreamweaver.
odinsdream
http://ca.php.net/manual/en/intro.pdo.php ships with PHP 5.1 (and higher) so you might already have it. It parameterizes and prepares plain old fashioned queries for execution. It's fairly easy (as in not much work) to refactor an existing codebase to use, and it handles things like properly escaping strings to prevent sql injection. A simplified but not atypical usage would be something to the effect of: $statement = $db->prepare( "select * from foo where bar = :baz" ); $statement->bindParam( ':baz', $baz, PDO::PARAM_STR ); $statement->execute(); while( $row = $statement->fetch( PDO::FETCH_ASSOC ) ) { echo $row['columnName']; }
cCranium
Yeah, prepared statements or stored procs. Call either like a function; in fact you'll wat to make them only accessible through a function that validates/sanity checks the data (or at least the data's type, given that PHP is weakly typed), so they can only be called with valid data. Note that for selects with optional predicates, you can still have one SP, by using the null parameter trick. Consider the following sql statements: select * from person where lastname = ?; select * from person where lastname = ? and firstname= ?; select * from person where firstname= ?; Can you write this as one SP, rather than as three? Yes. Can you do that without putting all three statements and three "if" statements in the SP? Also yes. create proc find_person( @ln varchar, @fn varchar) as begin select * from person where ( lastname = @ln or @ln is null) and ( firstname = @fn or @fn is null); end; Then pass null for the parameters you don't care about, the values that should be "unbound". While this'll work on any RDBMS, some optimize the null out better than others (Sybase optimizes it well, MSSQL Server not so well), so if you do this, run a showplan. For prepared statements, this is less necessary, as you can create the prepared statement dynamically, while dynamically creating an SP shouldn't be allowed.
orthogonality
Related Q & A:
- How can I optimize this dynamic SQL query in oracle with PL/SQL?Best solution by docs.oracle.com
- How to prevent an SQL injection in PHP?Best solution by Stack Overflow
- How do I avoid the friend zone/not be too much of a nice guy?Best solution by psychologytoday.com
- How do you avoid saggy skin during and after weight loss?Best solution by Yahoo! Answers
- How can I avoid getting tired while I study?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.