echo full joomla query (with limit etc)? - php

I was wondering if there was a way to echo out the full query with limit and limitstart etc. I can echo out the line $query, but i want to see why the limit isn't working and I can't seem to get it to display the actual query that it's sending to the database.. Here's the code:
$params =& JComponentHelper::getParams('com_news');
$limit = $params->get('x_items', 5);
$limitstart = JRequest::getVar('limitstart', 0);
$query = "SELECT * FROM #__news WHERE published = 1 AND catid = ".$Itemid." ORDER BY date DESC";
$db->setQuery($query, $limitstart, $limit);
$rows = $db->loadObjectList();
$db->getQuery($query, $limitstart, $limit); is only displaying "SELECT * FROM jos_news WHERE published = 1 AND catid = 8 ORDER BY date DESC" which doesnt have the LIMIT params on the end of the query..
Any help would be appreciated :)

The JDatabaseQuery object has a __toString() function that outputs the query so you can do:
echo $db->getQuery();
Or if you want to pass it to a function you can explicitly cast it to a string first:
var_dump((string)$db->getQuery());

var_dump($db);die;
Do that after the loadObjectList() call. Inside the $db variable there must be a _sql attribute that is the last query executed.

Agreed with the previous answers, but... In case you are developing your own components, since I often want to know for sure what exactly is executed too, here's a simple solution:
In your models put:
$db = JFactory::getDBO();
echo $db->getQuery();
Where you want to know the query... Don't put it in (for example) your view, since it might have loaded some other dropdown list by way of execution in the meantime...
For example:
For a list-view put it right before the foreach ($items... in the public function getItems() of the model.
In a form-/item-view put it right before the return $data / return $item in the protected function loadFormData() / public function getItem($pk = null)
Hope this helps...

On new joomla versions, you need to echo __toString() on query object.
echo $query->__toString();
I get this info on this joomla answer.
Hope this helps

Joomla provides $query->dump(). To add convenience, I like to wrap it in enqueueMessage() so that the presented string is at the top of the webpage.
JFactory::getApplication()->enqueueMessage(
$query->dump(),
'notice'
);
IMPORTANT: You should never show the raw SQL string or a raw query error string to the public.
See some of my implementations at Joomla Stack Exchange.

Related

SQL query result to string

I'm using SQL in Yii framework.
I need to show the person's latest active week (it's number and date).So I wrote following code:
public function latestWeek()
{
$datalogin=//the login is working fine
$sql ="SELECT w.number,MAX(w.start_date)
FROM tbl_person_week t, tbl_week w
WHERE t.person_id=$this->id AND t.week_id=w.id";
$query = mysqli_query($datalogin, $sql);
return $query;
}
Now , I checked this query on the server and it works fine (almost) but first thing: I need to convert it into string , because yii's CgridView can't read it , and I couldn't find a working solution for this.
Second: on the server , it gave me the max date indeed , but not it's correct number , but the first number available. How can I fix this as well?
Queries like that should never be used in objective framework. If yu want to execute your own query, you should do it this way:
$sql = "your sql code";
$array = Yii::app()->db->createCommand($sql)->queryAll();
As result you will get multidimensional array with selected columns and rows
If you want to use it in grid view, you should do it this way:
$count = Yii::app()->db->createCommand($sql)->queryScalar();
$dataProvider = new CSqlDataProvider($sql, array('totalItemCount'=>$count));
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'grid-id',
'dataProvider'=> $dataProvider,
));
You can also use connection other than Yii::app()->db. Check CDbConnection class in docs.
edit: if you wanna use queries like mysql_fetch_assoc, check out also queryRow() method instead of queryAll()
Use Mysql_fetch _array
public function latestWeek()
{
$datalogin=//the login is working fine
$sql ="SELECT w.number,MAX(w.start_date)
FROM tbl_person_week t, tbl_week w
WHERE t.person_id=$this->id AND t.week_id=w.id";
$query = mysqli_query($datalogin, $sql);
while($row = mysqli_fetch_array($query)){
echo $row;
}
}
Assuming from your qu. that you want the week number and start date as one string, you have to concatenate the two columns in the sql.
You also need to specify that the week number is from the row with the maximum start date, which isn't as simple as you might first think.
I don't like injecting the person_id straight into SQL, it isn't awful in this case but is a bad habit to get into security-wise. There are binding methods available in the framework and I agree with Arek, that you should lean on the yii framework as much as possible.
To get the scalar string value, if you are insisting on using your own SQL.. I suggest the following:
$sql='
SELECT CONCAT('Week ',tw.number,' starting ',tw.start_date)
FROM tbl_week tw
JOIN (
SELECT MAX(twi.start_date) max_start_date
FROM tbl_week twi
JOIN tbl_person_week tpwi
ON tpwi.week_id = twi.id
AND tpwi.person_id = :person_id
) i
ON tw.start_date = i.max_start_date;
';
$command=Yii::app()->db->createCommand($sql);
$command->bindParam(":person_id", $this->id);
return $command->queryScalar();

Array_Rand always returns same value PHP fetch array

I have this function:
function set_spell() {
global $connection;
$query = "SELECT * FROM Spells";
$result_set = mysqli_query($connection, $query);
$spell_id_list = mysqli_fetch_array($result_set);
return $spell_id_list;
Then I try to output a random ID from the array, but I always get ID 1.
$spell_id_list = set_spell();
echo $spell_id_list[array_rand($spell_id_list)];
When I run this query in MYSQL, I get a list of all ID's as expected. Why doesn't the code above select one at random?
This is probably a stupid questions that I'll smack myself after I see the answer... but I've been stuck for longer than I think I should be on it.
Thanks for the help.
You just returning only single result from your function so either create array of all fetched results & return the same, or simply use order by rand() in your query,
SELECT * FROM Spells ORDER BY RAND();

Close session after executing database query

I have very little experience with joomla and sql and I would really appreciate your help!
I am using joomla 2.5 and I am querying data from the database and storing it in memory with the following code:
function getList()
{
$mainframe = JFactory::getApplication('site');
$db = JFactory::getDBO();
$query = " SELECT
*
FROM
#__ListUser
WHERE
$db->setQuery( $query );"
$rows = $db->loadObjectList();
return $rows;
}
I have 3 questions,
When I query the database, a new DB session is opened, Do I need to close it after or is automatic?
Do you know of a more efficient way to achieve this method (a user session memory size is about 11MB!)
Is there any security issue with accessing the database using this method?
Thank you very much! any help would be very appreciated!
The code should look like this (I don't see how it can work now):
function getList()
{
// $mainframe = JFactory::getApplication('site'); // you don't need this line!
$db = JFactory::getDBO();
$query = " SELECT
*
FROM
#__ListUser
WHERE
1=1"; // just some condition to extract selected rows
$db->setQuery( $query ); // this sets the query and it's joomla, not sql.
$rows = $db->loadObjectList();
return $rows;
}
Please note the WHERE .... needs a condition (else if you want all the rows, remove WHERE and what follows)
You don't need to close it
11Mb is not necessarily due to that query, try adding LIMIT 0,1 (to return just one row) you'll see your memory doesn't change much. Turn on debug in the global configuration, and reload the component. At the very bottom of the page you'll see which extensions are eating up your memory. 11Mb is acceptable though on most installations.
Should you create your WHERE condition using input params, just make sure you $db->quote() any values to prevent SQL-injection.
Try
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quote('*')
->from($db->quoteName('#__Listuser') // Do you really have upper case there?
->where('your condition with proper quoting');
$db->setQuery($query);
$rows = $db->loadObjectList();
1.
UNCOOL:
If you want to close or disconnect the database-session, you may use:
$db->disconnect(); // See: http://api.joomla.org/cms-3/classes/JDatabaseDriver.html#method_disconnect
But i guess, that the database-connection for every other module, plugin or template that want to use JFactory::getDBO(); is also closed then and needs to be reopened.
BETTER:
You should use FREE RESULT instead after a query is transfered to a PHP-Variable: http://api.joomla.org/cms-3/classes/JDatabaseDriverMysql.html#method_freeResult
$db->freeResult();

php function save result at array

hello i want to create function with returning data, for example when i have the function advert i want to make it every time show what i need, i have the table id, sub_id, name, date, and i want to create the function that i can print every time what i need advert(id), advert(name), i want to make it to show every time what i need exactly and i want to save all my result in array, and every time grab the exactly row that i want
<?php
function advert($data){
$id = $_GET['id'];
$query = mysql_query("SELECT *FROM advertisement WHERE id = $id");
while($row = mysql_fetch_assoc($query)){
$data = array(
'id' => $row['id']
);
}
return $data;
}
echo advert($data['id']);
?>
but my result every time is empty, can you help me please?
There are so many flaws in this short piece of code that the only good advice would be to get some beginners tutorial. But i'll put some effort into explaining a few things. Hopefully it will help.
First step would be the line function advert($data), you are passing a parameter $data to the method. Now later on you are using the same variable $data in the return field. I guess that you attempted to let the function know what variable you wanted to fill, but that is not needed.
If I understand correctly what you are trying to do, I would pass in the $id parameter. Then you can use this function to get the array based on the ID you supplied and it doesnt always have to come from the querystring (although it could).
function advert($id) {
}
Now we have the basics setup, we want to get the information from the database. Your code would work, but it is also vulnerable for SQL injection. Since thats a topic on its own, I suggest you use google to find information on the subject. For now I'll just say that you need to verify user input. In this case you want an ID, which I assume is numeric, so make sure its numeric. I'll also asume you have an integer ID, so that would make.
function advert($id) {
if (!is_int($id))
return "possible SQL injection.";
}
Then I'll make another assumption, and that is that the ID is unique and that you only expect 1 result to be returned. Because there is only one result, we can use the LIMIT option in the query and dont need the while loop.
Also keep in mind that mysql_ functions are deprecated and should no longer be used. Try to switch to mysqli or PDO. But for now, i'll just use your code.
Adding just the ID to the $data array seems useless, but I guess you understand how to add the other columns from the SQL table.
function advert($id) {
if (!is_int($id))
return "possible SQL injection.";
$query = mysql_query("SELECT * FROM advertisement WHERE id = $id LIMIT 1");
$row = mysql_fetch_assoc($query);
$data = array(
'id' => $row['id']
);
return $data;
}
Not to call this method we can use the GET parameter like so. Please be advised that echoing an array will most likely not give you the desired result. I would store the result in a variable and then continue using it.
$ad = advert($_GET['id']);
if (!is_array($ad)) {
echo $ad; //for sql injection message
} else {
print_r($ad) //to show array content
}
Do you want to show the specific column value in the return result , like if you pass as as Id , you want to return only Id column data.
Loop through all the key of the row array and on matching with the incoming Column name you can get the value and break the loop.
Check this link : php & mysql - loop through columns of a single row and passing values into array
You are already passing ID as function argument. Also put space between * and FROM.
So use it as below.
$query = mysql_query("SELECT * FROM advertisement WHERE id = '".$data."'");
OR
function advert($id)
{
$query = mysql_query("SELECT * FROM advertisement WHERE id = '".$id."'");
$data = array();
while($row = mysql_fetch_assoc($query))
{
$data[] = $row;
}
return $data;
}
Do not use mysql_* as that is deprecated instead use PDO or MYSQLI_*
try this:
<?php
function advert($id){
$data= array();
//$id = $_GET['id'];
$query = mysql_query("SELECT *FROM advertisement WHERE id = $id");
while($row = mysql_fetch_assoc($query)){
array_push($data,$row['id']);
}
return $data;
}
var_dump($data);
//echo advert($data['id']);
?>

Writing SQL Queries in Codeigniter 2.0

I have the following function that does not work and I'm having the hardest time trying to figure it out. I'm 12 and just learning, so forgive me:
function get_answer() {
$answer = $this->db->query("SELECT COUNT(questions) FROM possible_quest WHERE questions='something'");
return $answer;
}
When I run the following SQL query in phpmyadmin, it returns the expected result
SELECT COUNT(questions) FROM possible_quest WHERE questions='something'
How do I get this working in CodeIgniter using my function above?
The PHP error I get is
A PHP Error was encountered
Severity: 4096
Message: Object of class CI_DB_mysql_result could not be converted to string
Could be:
function get_answer()
{
$query = $this->db->query("SELECT COUNT(questions) AS count FROM possible_quest WHERE questions='something'");
$count = $query->row(); // returns an object of the first row
return $count->count;
// OR
$count = $query->row_array(); // returns an asociative array of the result
return $count['count'];
}
Another thing: if you want to pass 'something' as a variable, you can use parametrized query, like
$sql = "SELECT COUNT(questions) AS count FROM possible_quest WHERE questions = ?";
$query = $this->db->query($sql, array($something));
which has the benefit of escaping automatically your variable, so you don't worry about sql injections.
You need to setup to the count.
Heres what you need to do is
$answer = $this->db->query("SELECT COUNT(questions) as count FROM possible_quest WHERE questions='something'")->first_row()->count;
//$answer is now setup to be count
One line. Thats the beauty of CI
You're getting that error because
return $answer;
should be
return $answer->result();
The error you are getting is related to the fact that $this->db->query returns a result object, so you cannot use $answer directly as a string.
I suggest that you use print_r($answer) to see what could be going wrong with your conversion of objects to strings, if you have such a function in your model.
CodeIgniter has functions for building queries and returning the count:
function get_answer() {
$this->db->from("possible_quest");
$this->db->where("questions", "something");
return $this->db->count_all_results();
}
NOTE: The name of the function 'get_answer' doesn't match what you're actually doing. It looks like you're getting a count of questions, not an answer, so you should name it to something that makes more sense, like 'get_question_count'.
I recommend you to use an Active Record with method chaining when possible:
public function getAnswer() {
return
$this->db->
select('id')->
where('questions', 'something')->
get('possible_quest')->row()->count
;
}
or
public function getAnswer() {
return
$this->db->
select('id')->
from('possible_quest')->
where('questions', 'something')->
get()->row()->count
;
}
It's secure, easy to use, easy to understand and read. Don't listen to people saying that a single-line code is something good because a good code should be readable.

Categories