Reason to separate query and result? - php

Is there any reason why you should separate query and result when writing code, other than maybe readability?
Example separate:
$query = "SELECT * FROM foo ORDER BY foo2 DESC LIMIT 10";
$result = mysqli_query($dbconnect,$query);
compared to single line:
$result = mysqli_query($dbconnect,"SELECT * FROM foo ORDER BY foo2 DESC LIMIT 10");
I usually use the 1st example but have found myself using the 2nd single line example more and more of late as its quicker and easier to write so thought I'd ask before it becomes 2nd nature and then find out its really bad and may blow up the world or something 0.o

This is more of a preference, but readability is certainly a strong justification. However, I would also argue that scalability and maintainability of the query might also be a fitting arguments as well. suppose you have a complex query with multiple variables being sanitized for SQL injections with joins as so forth. In other words a long query:
$result = mysqli_query($dbconnect,"SELECT * FROM foo, bar Where col1.bar = (Select col1 From someTable where {$varibale} = ...) Group By ... ORDER BY foo2 DESC LIMIT 10");
Stuffing all of that into the function makes it difficult to read and anoying to maintain as well.

To give an answer to this question. Do like you want (or almost).
Like I said, the first way is maybe used due to the historical where we was limited to 80 characters. But this restriction doesn't exist anymore (and we have bigger screens). By the way, I don't tell you to put 300 characters per line.
Use the one you feel more readable / maintainable with. The only drawback can be your coworkers. They can dictate which one you must use.

Actually you could write your whole source in one line.
(Minimize source = Delete all spaces and linebreaks)
of course not in strings :)
Effect is: (1 Positive and 3 Negative to do this)
Bad readability (-)
Faster parsing (+)
Slow editing source (-)
No good maintainability (-)
Not writing everything to one line
Effect is: (3 Positive and 1 Negative to do this)
Good readability (+)
Little bit slower parsing (-)
Fast editing source (+)
Better maintainability (+)
(Guess you only feel the parsingtime difference in very large codefiles)
This is how I decide to write my source.
Sometimes (for e.g. Plugins) I use the minimized version.

for me, its all about readability. I write a ton of code. and release app. 6 months later when i go back to fix a bug, I need to quickly find things. I separate out as much as I can. Parsing times are minimal unless you are writing incredibly large volumes of code. its all about readabilty for me. I go one step further to make it as pretty as possible.
$select = "SELECT x,y,z";
$from = " FROM foo,bar,table3";
$order = " ORDER BY foo2 DESC ";
$limit = " LIMIT 10";
$query = $select . $from . $order . $limit;
$result = mysqli_query($dbconnect,$query);

I think it's just a preference too. I usually use the short way for short and "unvarying" requests.
But for longer requests, it's easier to read and maintain taken separately.
Especially for "dynamic requests" (partly depending on external conditions): it's sometimes easier to work on a string, for example to concatenate a where clause, or another, or none at all, depending on a condition.
An example I have in mind: a "list.php" script displaying all articles if called with no parameter, and filtering articles of a specific category 'foo' if called with get-parameter ?cat=foo given.
I personally find it easier to read and maintain like this:
$query="select name, description, price from articles";
if(isset($_GET['cat'])) $query.=" where cat={$_GET['cat']}";
$result = mysqli_query($dbconnect,$query);
Of course it could also be done directly in the one-line version using ternary (?:) operators, but then readibility suffers a bit:
$result = mysqli_query($dbconnect,"select name, description, price from articles".(isset($_GET['cat'])?" where cat={$_GET['cat']}":""));
It becomes really much more unreadable and unmaintainable if you add other conditions. For instance, a second filter on get-parameter `?supplier=bar"...
[EDIT:] I just had the case: when your request fails, it's easier to debug when the query stands in a string. A simple echo $query; allows you to see exactly what you're sending to the DB server...
In following php code: $query="select * from $userTable where id=:uid";, you might oversee that $userTable wasn't defined...
but after an echo $query;, you can't oversee that there's something missing here: $query="select * from where id=:uid";...

Related

select from a select statement in php & mySQL

I am trying to add filters to a DB search. I have a search that takes some text and tries to find items with that text in the title. I also have a price range filter. That code is below and works just fine
$sql = "SELECT * FROM items where title LIKE '%". $title ."%' AND price > '". $price1 ."' AND price < '".$price2."' Limit 70";
Now I am trying to more and more filters. Is there a select from the above code's output? I don't want to just keep making a longer SELECT statement with tons of if statements. I'd prefer to take the output of the previous select and refine that with another select. Is this possible?
EDIT 1 Context:
Users are the ones entering the information. This is for searching the items on my site.
There's no other useful way than adding lots of different conditions to your WHERE cause, if you use plain SQL. It is possible to use several nasted SELECT statements in your query, but this makes your code neither any more readable nor faster.
A more elegant solution is the usage of query objects or another form of object-oriented query abstraction (e.g. ZendDB).
You can use some of the mysql string functions like INSTR(), MATCH which will make your life a little easy and also help the readability of the code.
You can also use REGEXP and NOT REGEXP for pattern matching . The list of string functions are here.

Is there any simplification for this? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is there any simplification for this?
$query = $this->link->prepare('SELECT * FROM test WHERE id = :id LIMIT 1')
$query->bindParam(':id', $id);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
unlink($row['avatar']);
$query = $this->link->prepare('DELETE FROM test WHERE id = :id LIMIT 1');
$query->bindParam(':id', $id);
$query->execute();
I don't like to advise people to skip using query parameters. You should get into the habit of doing it.
It's actually not hard, and it makes it simpler to write queries because you never have to think about whether you got the right kind of escaping and quoting. I find it makes my code look more clear.
I've always been puzzled how people learn that they need to use bindParam() for everything with PDO. It's simpler in most cases to pass an array of parameters to execute(). The only case when I typically use bindParam() is if I need to pass a NULL value.
Also you don't need to use named parameters, you can use positional parameters (but don't mix these parameter types in a given query).
fetchColumn() is simpler if you only need one column. Speaking of which, avoid SELECT * when you don't need all the columns.
If you are querying for a specific id, assuming that's the primary key, then you don't need LIMIT 1. There can be at most one row for a specific value in any unique key.
I assume you've enabled the exception-based error reporting. If not, you should check the result from each call to prepare() and execute() because they return false on error.
$query = $this->link->prepare('SELECT avatar FROM test WHERE id = ?')
$query->execute([$id]);
$avatar = $query->fetchColumn();
unlink($avatar);
$query = $this->link->prepare('DELETE FROM test WHERE id = ?');
$query->execute([$id]);
PS: The short syntax for arrays, like [$id], requires PHP 5.4
Thank you for the good question. To my utter disappointment, such questions are extremely rare on this site.
Is there any simplification for this?
Sure.
This is called "programming".
Although for the average PHP user programming stands for just putting several predefined blocks together, like LEGO bricks, in reality programming stands more for invention, for creating something new. And no less for optimizing too, for taking less moves for the same action.
A programmer could always create a function to encapsulate repeated tasks. Eventually he may wish to put such functions together into a class, but that's not the point.
As you can see, most of your operators just repeated ones. Every time you see a repetition you know for sure there can be a function or at least a loop.
Here is your code using my attempt in programming, aimed (beside extra safety) to the very code shortening:
$name = $this->link->getOne('SELECT avatar FROM test WHERE id = ?i', $id)
unlink($name);
$this->link->query('DELETE FROM test WHERE id = ?i', $id);
As you can see, this code is Extra DRY (stands for Don't Repeat Yourself) - all the repeated code is just taken away into internals.
Well, as you can see, my class is built upon mysqli. but of course something similar can be done even using ugly PDO, using wrapper sort of one I posted recently:
$name = $this->link->query('SELECT avatar FROM test WHERE id = ?', [$id], "one");
unlink($name);
$this->link->query('DELETE FROM test WHERE id = ?', [$id]);
By the way, taking programming little further you may shorten this code even more:
unlink($avatar_dir.$id.".png");
$query = $this->link->query('DELETE FROM test WHERE id = ?i', $id);
as avatar image obviously don't need no dedicated name and just id can serve perfectly, saving you extra field in database and extra query. All avatars can be converted to single format at the time of upload, to reduce the headache even more.

PHP/SQL: framework query building vs string concatenation

Consider 2 ways of querying the database:
With a framework (Yii):
$user = Yii::app()->db->createCommand()
->select('id, username, profile')
->from('tbl_user u')
->join('tbl_profile p', 'u.id=p.user_id')
->where('id=:id', array(':id'=>$id))
->queryRow();
With string concatenation (separating individual parts of a SQL statement):
$columns = "id,username,profile"; // or =implode(",",$column_array);
//you can always use string functions to wrap quotes around each columns/tables
$join = "INNER JOIN tbl_profile p ON u.id=p.user_id";
$restraint = "WHERE id=$id ";//$id cleaned with intval()
$query="SELECT $columns FROM tbl_user u {$restraint}{$join}";
//use PDO to execute query... and loop through records...
Example with string concatenation for pagination:
$records_per_page=20;
$offset = 0;
if (isset($_GET['p'])) $offset = intval($_GET['p'])*$records_per_page;
Squery="SELECT * FROM table LIMIT $offset,$records_per_page";
Which method has better performance?
PHP's PDO allows code to be portable to different databases
2nd method can be wrapped in a function so no code is ever repeated.
String concatenation allows building complex SQL statements programmatically (by manipulating strings)
Use which is right for you and your project team. Frameworks are written for a reason, so use them if it suits, but if it doesn't (and there are reasons they don't) then fall away.
I don't know Yii, but if you look at a lot of frameworks, all they do is build a string query from the parts at the end of the day, hopefully taking advantage of parametization but not always. So, regarding speed, string concat is probably "fastest" - but you're unlikely to really see the difference with a stop watch (you could benchmark if you needed with 1000 queries, but other features such as better error checking or caching may unfairly slow or speed up hte results).
But one advantage frameworks have is they can add context-sensitive caching and know when you update table X that you query caches for A, D and F need to be deleted, but queries B, C and E are all good.
You also have "easy to read" and "debug" and "functionality" to worry about. The top example is much easier to read, which is important in a shared project.
You also need to consider prepared statements - does the framework use them? If so, does it allow you to re-use them (as opposed to merely using them for syntax purposes).
But can the framework do sub-selects? Can it do parametization inside the "JOIN ON"? If not, string concatination with PDO may be more appropriate.
It's not a hard and fast answer - but hopefully provides all the points you need to consider.
Recommendation: use framework unless you really notice it being slow, using too much memory or there is some other good reason not to.

Any value of separating a MySQL query into $query and $result?

I always see MySQL queries structured like this, even with the simplest of queries:
$query = "SELECT * FROM table_name WHERE id = '1'";
$result = mysql_query($query);
Is there any value, time or otherwise in doing the above over a simple one line query such as?
$result = mysql_query("SELECT * FROM table_name WHERE id = '1'";
I've always used the former, as when I started using PHP I thought it best to simply copy everyone else, however now that I'm working on a fairly large (relative to my other work) application, I could cut out a significant amount of arbitrary coding if there's really no difference.
Generally, I like separating them because I can easily do print $query; when I'm trying to figure out why my query won't work. It's mostly a matter of personal preference.
With the first, it's easier to log the SQL in case something went wrong (and it's easier to spot typos, like a missing bracket).
Actually there is no difference at all except for one thing. If you put your query in seperate variable then you can reuse that. If any changes occur in query you just need to edit the query in variable
You can always create a custom function that takes in a query and runs it, and pass additional optional arguments in case you want it to return the query, or log the query to track any issues etc.
Is there any value, time or otherwise in doing the above over a simple one line query such as?
sure, as MSpreij said, you can examine your query in case of error.
I always see MySQL queries structured like this, even with the simplest of queries:
$query = "SELECT * FROM table_name WHERE id = '1'";
$result = mysql_query($query) or trigger_error(mysql_error()." ".$query);
this simple construct will save you a dozen whines in stackoverflow "what does it mean mysql_fetch_array(): supplied argument is not a valid MySQL result"
notice the additional part. This is called programming.
It will print your query automatically, in case of error, along with mysql error message. Or log it into error log in a live server with appropriate settings.
Without writing print $query; manually.
However, both methods are ugly as hell.
One should never use raw API functions at all.
It's ugly, unmaintainable, bloated and repetitive.
One should develop a library, a function to make a call more intelligent and less repetitive
$data = mydb_get_row("SELECT * FROM table_name WHERE id = 1");
having all the processing inside. with error handling, query logging, parameter checking and api functions calling.
yet as a true one-liner, not a silly one you were trying to achieve.

Is there a better, more "Standard" way to perform SQL queries in PHP without using a framework?

For the longest time, I've been using the following basic formatting for SQL queries within my PHP:
$sql = "SELECT * FROM `user-data` WHERE `id` = '".$id."' LIMIT 1;";
$fn = mysql_fetch_assoc(mysql_query($sql));
While this works flawlessly, it can get really messy for longer bits of code, and something deep inside of my conscience cringes at the string concatenation every time I do it. Still, it works and I use it almost everywhere without major issues. (That's a tame example, I'm not dense enough to pass user data directly into an SQL string without escaping it first, etc etc.)
What I'd like to do is something a bit more object oriented, but I'm not sure what the best approach would be. It'd be nice to just be able to sql->insert($values [, $where, $extra]); or something similar, using PHP's natural Associative Array types to pass in the query strings in a more simplified manner. Less flexible? Yes. More readable? Heck yes, and harder to make "silent" syntax errors at that.
What are the community's takes on this? What approaches have you seen to this problem that were the most effective for projects you were working on?
Not that it matters, but I personally don't do much more complicated than SELECTs, INSERTs, and UPDATEs, with occasional nesting of subqueries, but that's mostly because my SQL flavor doesn't do stored procedures.
PDO is a good, solid, secure solution that many frameworks build off of. If you're going to start from the bottom, PDO is a solid foundation.
Maybe it would make you a little happier at least to use PHP's string variable substitution:
$sql = "SELECT * FROM `user-data` WHERE `id` = '$id' LIMIT 1;";
There is MDB_QueryTool I never tried.
IMHO Zend_DB is really cool, the zend framework allow you to use only the part you are interested in so you might want to take it a look event if you don't want the full framework.
what I like in Zend_DB is the table select syntax
$userRowset = $user->fetchAll( $user->select()
->where('name LIKE ?', $name . '%')
->order('id ASC')
->limit(10)
);
You can easily see all the criterias and table involved so I find better then doing plain SQL. Just one warning Zend_DB doesn't handle all the SQL, so time to time you would have to write plain SQL but that's really rare.
Doctrine is an ORM wrapped around PDO.
Another vote for doctrine. Don't waste your time with PDO. I can't emphasize this enough. Go with an orm. Forget about wasting time writing CRUD methods, custom caching logic, and worrying about premature optimization such as "overhead" resulting from a library. The overhead incurred by spattering statements like "select * from app_users" and their associated ugly heredocs isn't worth it.
If you need to fall back to sql, you can. The other 90% of the time you're in a state of bliss.
http://www.doctrine-project.org/
You can use mysqli to write little place holders in you SQL and then fill them in. It should be less susceptible to SQL injection attacks than string concatenation.
$conn = new mysqli($server, $username, $password, $database);
$stmt = $conn->prepare('SELECT * FROM people WHERE age = ? AND name != ?');
$stmt->bind_param('is', 20, "Austin");
Try:
$stat2 = <<<SQL
SELECT * from YOUR.DET_TABLE
WHERE ID = ?
ORDER BY ID, EFF_DT
SQL;
$d_cur = $conn->prepare($stat2);
$status = $d_cur->execute(array($selected));
I've been wondering why I am always seeing the more complicated form of string building like this:
"literal string " . $a . " more literal", rather than "literal string $a more literal", or in your case:
"SELECT * FROM `user-data` WHERE `id` = '".$id."' LIMIT 1;";
instead of this:
"SELECT * FROM `user-data` WHERE `id` = '$id' LIMIT 1;";
For more complicated expressions, I like to use sprintf (but I was a c programmer for a long time):
$sql = sprintf("SELECT * FROM `user-data` WHERE `id` = '%s' LIMIT 1", $id);
This can also be written in this format:
$sql = sprintf("
SELECT *
FROM `user-data`
WHERE `id` = '%s'
LIMIT 1",
$id);
In this case, it doesn't buy much, but when there are several variables embedded in the string, it makes it easier to manage.

Categories