I am trying to figure out how to get JSON array with following format
[
["2016-02-26","5190","1253","425","123"],
["2016-02-27","5209","1114","521","214"],
["2016-02-28","5142","1425","412","156"],
["2016-02-29","5523","1365","632","198"],
["2016-03-01","5125","1452","523","152"],
["2016-03-02","5000","1245","741","286"]
]
But currently I am getting
[{"date":"2016-02-26","visitors":"5190","registered":"1253","downloaded":"425","sticky_activity":"123"},
{"date":"2016-02-27","visitors":"5209","registered":"1114","downloaded":"521","sticky_activity":"214"},
{"date":"2016-02-28","visitors":"5142","registered":"1425","downloaded":"412","sticky_activity":"156"},{"date":"2016-02-29","visitors":"5523","registered":"1365","downloaded":"632","sticky_activity":"198"},
{"date":"2016-03-01","visitors":"5125","registered":"1452","downloaded":"523","sticky_activity":"152"},
{"date":"2016-03-02","visitors":"5000","registered":"1245","downloaded":"741","sticky_activity":"286"}]
Here is my function, if it's gonna help
public function dataAction(Request $request){
$em = $this->getDoctrine()->getEntityManager();
$connection = $em->getConnection();
$sqlQuery = "SELECT DATE_FORMAT(date, \"%Y-%m-%d\") as date,visitors, registered, downloaded, sticky_activity
FROM engagement";
$statement = $connection->prepare($sqlQuery);
$statement->execute();
$queryResult = $statement->fetchAll();
return new JsonResponse($queryResult);
}
Return this:
return new JsonResponse(array_map('array_values', $queryResult));
By the way you should also avoid direct SQL calls in favor of DQL or query builders. These are good practices while using Doctrine. Its goal is to avoid SQL as much as possible.
Related
I've just created a simple API for a CAD/MDT I'm working on, I've managed to get it to show the correct information when I do /citations/userid/1. This will then display all the correct values from the SQL database however, if I do /citations/issued_by/kevingorman1000 it will just throw an error. I can't tell what the error is as I'm using Slim php and can't seem to get the errors to display.
Any ideas why it isn't working ? I've added my code below..
$app->get('/citation/issuedby/{issued_by}', function(Request $request, Response $response){
$issued_by = $request->getAttribute('issued_by');
$sql = "SELECT * FROM ncic_citations WHERE issuedby = $issuedby";
try{
// Get DB Object
$db = new db();
// Call Connection to DB
$db = $db->connect();
$stmt = $db->query($sql);
$issby = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
echo json_encode($issby);
} catch(PDOExecption $e) {
echo '{"error"} : {"text": '.$e->getMessage().'}';
}});
Any ideas why this is the case? Does it only allow getting via number or do I need too do something else? First time using this and kinda new to PHP as well.
Thanks for any help.
Your problem is called SQL injection. You can solve it by using prepared statements. Never escape the values with quotes or anything else, as others might have suggested.
$sql = "SELECT * FROM ncic_citations WHERE issuedby = ? ";
$stmt = $db->prepare($sql);
$stmt->execute([$issuedby]);
$issby = $stmt->fetchAll(PDO::FETCH_OBJ);
For a good tutorial on PDO and prepared statements I recommend: https://phpdelusions.net/pdo
It's because SQL error (missing quotes around string).
You try to send query
$sql = "SELECT * FROM ncic_citations WHERE issuedby = kevingorman1000";
Correct query has to be
$sql = "SELECT * FROM ncic_citations WHERE issuedby = 'kevingorman1000'";
I am trying to find a way to create a function in PHP that will wrap a SQL query given in the parameter so that I can prevent SQL Injection in the function that can then be called many times throughout my application. Rather than repeating the same statements for each and every query.
For example say I have the following PHP code that prepares and executes a query to prevent SQL injection:
$name = "$_POST['name']";
$stmt = $db->prepare('SELECT * FROM test_table WHERE test_name = ?');
$stmt->execute(array($name));
For each query my application will need to make these statements will need to be repeated. I want a way to prevent having to do this each time, rather I would simply want to call a function each time and pass in the query.
How would I wrap this in a function that can then be called whenever I need to make a query in my application, given that I do not know in advance the amount of parameters that would need to be parameterized. The above query has one parameterized query, but each query may have a different amount.
Note:
I am using PDO statements
Something like this:
public function query($query)
{
// statements here
}
Where the query is passed in as a parameter.
Does anyone know how I can achieve this?
Currently, I am using something like this that might work for you.
Example:
function superQuery($query, $params, $type = null) {
$pdo = new pdo(...);
$stmt = $pdo->prepare($query);
$stmt->execute($params);
if ($type === "select") {
$result = $stmt->fetchAll();
return $result;
} else {
return $stmt;
}
$query = "SELECT row FROM column WHERE row1 = ? AND row2 = ?";
$params = [$row1, $row2];
$type = "select";
$row = selectQuery($query, $params, $type);
// returns multidimensional array or true/false depending if argument is used //
There's lots of ways you can do it. You could also pass a count argument if you wanted to return a count instead of a result set. But hopefully this points you in the right direction and gives you some ideas.
Instead of removing my entities one by one with
$this->em->remove($price);
I would like to execute a native SQL query to delete all my entities.
Here is what I tried :
$sqlQuery = "delete from mytable where mytable.fieldone_id = ".$fieldoneid." and mytable.fieldtwo_id = ".$fieldtwoid.";";
$query = $this->getEntityManager()->createNativeQuery($sqlQuery);
$query->execute();
It returns the following error :
Catchable fatal error: Argument 2 passed to Doctrine\ORM\EntityManager::createNativeQuery() must be an instance of Doctrine\ORM\Query\ResultSetMapping, none given
It wants me to pass a ResultSetMapping, but it is a delete query...
Can anyone please teach me how to do it?
I use a different way of executing native SQL queries that is much easier, in my opinion. Try something like this (I am also using the PDO method of including variables in the query, which is safer):
$sql = "delete from mytable where mytable.fieldone_id = :fieldoneid and mytable.fieldtwo_id = :fieldtwoid";
$params = array('fieldoneid'=>$fieldoneid, 'fieldtwoid'=>$fieldtwoid);
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->execute($params);
// if you are doing a select query, fetch the results like this:
// $result = $stmt->fetchAll();
This works great for me, hope it helps
as per Doctrine 2 Native SQL documentation page:
If you want to execute DELETE, UPDATE or INSERT statements the Native SQL API cannot be used and will probably throw errors.
You can user DQL queries instead.
$query = $em->createQuery("DELETE FROM YourNamespace\YourBundle\Entity\YourEntity e WHERE e.fieldone_id = " .$fieldoneid . " AND e.fieldtwo_id = " . $fieldtwoid);
$query->execute();
If you want to use the native way in doctrine, you can use in the entity repository :
public function deleteUserNative(User $user): void
{
$this->getEntityManager()->getConnection()->delete('user', array('id' => $user->getId()));
}
And just call this in your controller :
$em->getRepository(User::class)->deleteUserNative($user);
Regards,
So i have a function thats supposed to handle all data execute operations: sql
function loadResult($sql)
{
$this->connect();
$sth = mysql_query($sql);
$rows = array();
while($r = mysql_fetch_object($sth)) {$rows[] = $r;}
$this->disconnect();
return $rows;
}
I want to convert it to pdo and this is what i have so far: pdo
function loadResult($sql)
{
$this->connect();
$sth = $this->con->prepare($sql);
//execute bind values here
$sth->execute();
$rows = array();
while ( $r = $sth->fetch(PDO::FETCH_OBJ) ) {$rows[] = $r;}
$this->disconnect();
return $rows;
}
Here is an example of a function on how am using it to view data from the database:
function viewtodolist()
{
$db=$this->getDbo(); //connect to database
$sql="SELECT * FROM mcms_todolist_tasks";
//maybe the bind values are pushed into an array and sent to the function below together with the sql statement
$rows=$db->loadResult($sql);
foreach($rows as $row){echo $row->title; //echo some data here }
}
I have just pulled out the important snippets so some variables and methods are from other php classes. Somehow, the mysql query works fine, but the PDO query is giving me headaches on how to include bindValue paremeters most probably in the viewtodolist() function to make it reusable. Any suggestions/recommendations are welcome.
Since your existing function accepts a fully-formed SQL string, with no placeholders, you don't need to use prepare + bind. Your code as written should work fine, or you could use PDO::query() to execute the SQL in one step.
If you want to use parameterised queries, then your loadResult function is going to have to change a bit, as is the way you write your SQL. The example SQL you give doesn't actually have anything in that could be turned into a parameter (column names and table names can't be parameters as discussed here), but I'll use an imaginary variation:
// Get the todo tasks for a particular user; the actual user ID is a parameter of the SQL
$sql = "SELECT * FROM mcms_todolist_tasks WHERE user_id = :current_user_id";
// Execute that SQL, with the :current_user_id parameter pulled from user input
$rows = $db->loadResult($sql, array(':current_user_id' => $_GET['user']));
This is a nice secure way of putting the user input into the query, as MySQL knows which parts are parameters and which are part of the SQL itself, and the SQL part has no variables that anyone can interfere with.
The simplest way of making this work with your existing loadResult function would be something like this:
// Function now takes an optional second argument
// if not passed, it will default to an empty array, so existing code won't cause errors
function loadResult($sql, $params=array())
{
$this->connect();
$sth = $this->con->prepare($sql);
// pass the parameters straight to the execute call
$sth->execute($params);
// rest of function remains the same...
There are cleverer things you can do with parameterised queries - e.g. binding variables to output parameters, preparing a query once and executing it multiple times with different parameters - but those will require more changes to the way your calling code works.
I want to execute raw SQL using Doctrine 2
I need to truncate the database tables and initialize tables with default test data.
Here's an example of a raw query in Doctrine 2 that I'm doing:
public function getAuthoritativeSportsRecords()
{
$sql = "
SELECT name,
event_type,
sport_type,
level
FROM vnn_sport
";
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
}
//$sql - sql statement
//$em - entity manager
$em->getConnection()->exec( $sql );
I got it to work by doing this, assuming you are using PDO.
//Place query here, let's say you want all the users that have blue as their favorite color
$sql = "SELECT name FROM user WHERE favorite_color = :color";
//set parameters
//you may set as many parameters as you have on your query
$params['color'] = blue;
//create the prepared statement, by getting the doctrine connection
$stmt = $this->entityManager->getConnection()->prepare($sql);
$stmt->execute($params);
//I used FETCH_COLUMN because I only needed one Column.
return $stmt->fetchAll(PDO::FETCH_COLUMN);
You can change the FETCH_TYPE to suit your needs.
Most of the answers here are now deprecated since Doctrine DBAL 2.13. For example, execute is deprecated and fetchAll will be removed in 2022.
/**
* BC layer for a wide-spread use-case of old DBAL APIs
*
* #deprecated This API is deprecated and will be removed after 2022
*
* #return list<mixed>
*/
public function fetchAll(int $mode = FetchMode::ASSOCIATIVE): array
It's no longer recommended to use execute and then fetchAll since both are deprecated.
* #deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead
* #deprecated Result::fetchAll is deprecated, and will be removed after 2022
So we have to be more specific when executing raw SQL as well as fetching result.
Instead of using Statement::execute(), we need to use executeQuery or executeStatement.
executeQuery return object Result:
Executes the statement with the currently bound parameters and return
result.
executeStatement return int:
Executes the statement with the currently bound parameters and return affected rows.
Instead of using Result::fetchAll(), we need to use fetchAllNumeric or fetchAllAssociative (and more).
To get a simple result, you would have to do:
public function getSqlResult(EntityManagerInterface $em)
{
$sql = "
SELECT firstName,
lastName
FROM app_user
";
$stmt = $em->getConnection()->prepare($sql);
$result = $stmt->executeQuery()->fetchAllAssociative();
return $result;
}
And with parameters:
public function getSqlResult(EntityManagerInterface $em)
{
$sql = "
SELECT firstName,
lastName,
age
FROM app_user
where age >= :age
";
$stmt = $em->getConnection()->prepare($sql);
$stmt->bindParam('age', 18);
$result = $stmt->executeQuery()->fetchAllAssociative();
return $result;
}
How to execute a raw Query and return the data.
Hook onto your manager and make a new connection:
$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();
Create your query and fetchAll:
$result= $conn->query('select foobar from mytable')->fetchAll();
Get the data out of result like this:
$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);
I found out the answer is probably:
A NativeQuery lets you execute native
SQL, mapping the results according to
your specifications. Such a
specification that describes how an
SQL result set is mapped to a Doctrine
result is represented by a
ResultSetMapping.
Source: Native SQL.
I had the same problem. You want to look the connection object supplied by the entity manager:
$conn = $em->getConnection();
You can then query/execute directly against it:
$statement = $conn->query('select foo from bar');
$num_rows_effected = $conn->exec('update bar set foo=1');
See the docs for the connection object at http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html
In your model create the raw SQL statement (example below is an example of a date interval I had to use but substitute your own. If you are doing a SELECT add ->fetchall() to the execute() call.
$sql = "DELETE FROM tmp
WHERE lastedit + INTERVAL '5 minute' < NOW() ";
$stmt = $this->getServiceLocator()
->get('Doctrine\ORM\EntityManager')
->getConnection()
->prepare($sql);
$stmt->execute();
You can't, Doctrine 2 doesn't allow for raw queries. It may seem like you can but if you try something like this:
$sql = "SELECT DATE_FORMAT(whatever.createdAt, '%Y-%m-%d') FORM whatever...";
$em = $this->getDoctrine()->getManager();
$em->getConnection()->exec($sql);
Doctrine will spit an error saying that DATE_FORMAT is an unknown function.
But my database (MySQL) does know that function, so basically what is happening is Doctrine is parsing that query behind the scenes (and behind your back) and finding an expression that it doesn't understand, considering the query to be invalid.
So if like me you want to be able to simply send a string to the database and let it deal with it (and let the developer take full responsibility for security), forget it.
Of course you could code an extension to allow that in some way or another, but you just as well off using mysqli to do it and leave Doctrine to its ORM business.