I try to remake methods which got queries from ids to methods which work with slugs.
So basically this:
public function view($id)
{
$id = (int)$id;
$this->db->where('id', $id)->get('recipes')
}
To this:
public function view($slug)
{
$this->db->where('slug', $slug)->get('recipes')
}
In the second method I'm aware that this is a xss not safe. I think that it will be best to remake all queries with query bindings.
Like so:
$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick'));
But I have too munch queries to remake is it possible to have some function whic to clean the slug from the codeigniter or something in the second method example?
Is it ok to use the security xss-clean method to the slug before to use it in the query:
$this->security->xss_clean($slug)
I guess all insert or update data come from a form, if you go to application/config/config.php and set
$config['csrf_protection'] = FASLE;
to
$config['csrf_protection'] = TRUE;
this helpyou to filter all inputs (xss_clean)
public function view($slug)
{
$slug_new=$this->db->escape_str(trim($slug));
$this->db->where('slug', $slug_new)->get('recipes')
}
Related
I want to display the content of page dynamically this following code is working fine but it only shows the content of specific id...how can i make that dynamic??
Model
public function getAllDepartment() {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID=15");
return $join->result_array();
}
Controller
public function reportDisplay(){
$data['clubs'] = $this->labdoc_model->getAllDepartment();
$this->load->view('SystemAdminUser/labreport', $data);
}
There is simple work around for this using Query Builder class of CI.
So this is how your code will look like,
$id=15;
$this->db->select('*');
$this->db->from('labreport_db');
$this->db->join('patient_db', 'labreport_db.P_ID = patient_db.id');
$this->db->where('labreport_db.P_ID', $id);
$query = $this->db->get();
This is standard approach in CI to make database operation using query builder class in which you can perform dynamic WHERE condition.
For which just change the value of $id and the query will do the needful.
Reference: https://www.codeigniter.com/userguide3/database/query_builder.html#selecting-data
Hold the id in some variable like:
$pid = $_REQUEST['p_id'];
// $_REQUEST['p_id'] will contain the dynamic value in it
and put this variable in your query like:
where labreport_db.P_ID = $pid;
It will show the data for the value contained in $pid, and make sure it contains the dynamic value in it.
You can used this code for you solution.
Model.php
public function getAllDepartment($pId) {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID=".$pId);
return $join->result_array();
}
Controller.php
public function reportDisplay(){
$pid = $_REQUEST['pid']; //OR $_GET['pid']; OR $_POST['pid']; You can pass your id for get content
$data['clubs'] = $this->labdoc_model->getAllDepartment($pid);
$this->load->view('SystemAdminUser/labreport', $data);
}
There are a couple of ways doing it. One of them is through CI routing ability.
Model
public function getAllDepartment($p_id = 0) {
$join = $this->db->query( "Select * from labreport_db inner join patient_db on labreport_db.P_ID=patient_db.id where labreport_db.P_ID={$p_id}");
return $join->result_array();
}
Comment: I added $p_id as a variable to fetch the ID dynamically.
Controller
public function reportDisplay($p_id = 0){
$data['clubs'] = $this->labdoc_model->getAllDepartment($p_id);
$this->load->view('SystemAdminUser/labreport', $data);
}
Comment: We also add a variable called $p_id in the reportDisplay function and pass it to your model's getAllDepartment()function.
How to fetch the report dynamically
I don't know your URL structure, but for example purposes let's say it's http://localhost/yourcontrollername/reportDisplay/
To access it dynamically, simply add an ID after the reportDisplay
For example:
http://localhost/yourcontrollername/reportDisplay/15
http://localhost/yourcontrollername/reportDisplay/10
I'm requesting the community's wisdom because I want to avoid bad coding practices and/or mistakes.
I'm having a php class wich is an objects manager. It does all the work with the database: inserting new data, updating it, getting it and deleting it (I've read it's called CRUD...). So it has a function that gets an element by id.
What I want to write is a function that gets a list of objects from the table.
I will then use a mysql query that goes something like
SELECT * FROM mytable WHERE column1='foo'
And then some order by and limit/offset.
However, in my application there are different cases in which I will need different lists from this table. The WHERE clause will then be different.
Should I write different functions, one per type of list?
Or should I write one generic function to which I will send arguments that then dynamically creates the query? If so, do you have any advice on how to do this properly?
EDIT:
Thanks for all your answers! I should tell that I'm not using any framework (maybe wasn't the best idea...), so I didn't know about query builders. I'll investigate that (either finding a standalone uery builder or migrating to a framework or writing my own, I don't know yet). That will be useful any time I need to execute a mysql query :-)
Although I'm still confused:
Let's say I need several lists of clients (objects), for example all clients, clients over 18, clients currently online...
What approach would be best to retrieve those lists? I can either have 3 functions in my clients manager
allClients() {//execute a specific query and return list of objects}
allClientsOver18() {//execute specific query and return list of objects}
allClientsOnline() {//execute specific query and return list of objects}
or I can have one function tht builds the query based on parameters
listClients($some, $parameters)
{
//Build the query based on the parameters (definitely need a query builder!)
//Execute the query
//return list of objects
}
Which approach would be best (I guess it depends on circumstances) and mostly, why?
Thanks in advance!
Rouli
Thanks for all the info on query builders, I didn't even know it existed! :-) However I'm still confused as to wether I should write one specific function for each case (that function can still use the query builder to write its specific query), or write one generic function that builds dynamically the query based onf parameters. Which would be better in which case? I've added an example in my question, hope it makes it clearer!
This depends on how often you use each of these isolated queries, how complex the conditions are and how often you my need to combine the conditions with other queries. For eaxample if each the "online" and "over18" are just simple conditions then you could just use the normal findBy logic from my example:
$table = new MyTable($db);
$onlineOnly = $table->findBy(array('is_online' => true), null, null);
$over18Only = $table->findBy(array('is_over_18' => true), null, null);
$onlineOver18 = $table->findBy(array('is_over_18' => true, 'is_online' => true), null, null);
If the query is more complex - for example to get over 18 clients you have to do:
select client.*, (YEAR(CURDATE()) - YEAR(client.birthdate)) as age
FROM client
WHERE age >= 18
Then its probably better to make this into a separate method or create methods to work on Query objects directly to add complex conditions for example - especially if you will need this condition in a few different queries in the app:
$table = new MyTable($db);
// creates a basic query defaulted to SELECT * FROM table_name
$query = $table->createQuery();
// adds the complex condition for over 18 resulting in
// SELECT table_name.*, (YEAR(CURDATE()) - YEAR(table_name.birthdate)) as age WHERE age >= 18
$over18 = $table->applyOver18Query($query)->execute();
This way you can apply your over 18 condition easily to any query with out manually manipulating the builder ensure that your over 18 condition is consistent. But for simplicity you could also have a convenience method like the following:
public function findOver18By(array $criteria, $limit = null, $offest = null) {
$query = $this->findBy($criteria, $limit, $offset);
$this->applyOver18Query($query);
return $query->execute();
}
Normally you would use some kind of query builder at the lower level like:
$query = $db->createQuery()
->select($fields)
->from($tableName)
->where($fieldName, $value);
$results = $query->execute();
Then you might have a class that makes use of this like:
class MyTable
{
protected $tableName = 'my_table';
protected $db;
public function __construct($db) {
$this->db = $db;
}
public function findBy(array $criteria, $limit = null, $offset = null) {
$query = $this->db->createQuery();
$query->select('*')->from($this->tableName);
foreach ($criteria as $col => $value) {
// andWhere would determine internally whether or not
// this is the initial WHERE clause or an AND clause
// something similar would happen with an orWhere method
$query->andWhere($col, $value);
}
if (null !== $limit) {
$query->limit($limit);
}
if (null !== $offset) {
$query->offset($offset);
}
return $query->execute();
}
}
Usage would look like:
$table = new MyTable($db);
$result = $table->findBy(array('column1' => 'foo'), null, null);
This is a lot to implement on your own. Most people use an ORM or a DBAL to provide these features and those are often included with a framework like Eloquent with Laravel, or Doctrine with Symfony.
I guess at start you should need some main data like
$main = [
'from' = '`from_table`',
]
Then you should add selects if had
$selects = ['fields1','field2'];
$where = ['some condition', 'other condition'];
Then you could
$query = "SELECT ".implode(',', $selects ." FROM ".$main['from']."
WHERE ".implode('AND ', $where .";";
That's some approaches for simple one table query.
If you need Joins, then $selects better would be make with aliasos, so no field will be lost if they are not different, like
select temp.id as temp_id , temp2.id temp2_id from temp
left join temp2 on temp2.temp_id = temp.id
Feel free to ask some questions, maybe i haven't told , but you should also check bound parameters with some functions to avoid sql injections
I suggest using a CLASS for your database which holds all your database accessing functions as it makes your code cleaner making it more easier to look through for errors or modifications.
class Database
{
public function connect() { }
public function disconnect() { }
public function select() { }
public function insert() { }
public function delete() { }
public function update() { }
}
sample connect function for connecting to a selected database.
private db_host = ‘’;
private db_user = ‘’;
private db_pass = ‘’;
private db_name = ‘’;
public function connect()
{
if(!$this->con)
{
$myconn = mysqli_connect($this->db_host,$this->db_user,$this->db_pass);
if($myconn)
{
$seldb = mysqli_select_db($this->db_name,$myconn);
if($seldb)
{
$this->con = true;
return true;
} else
{
return false;
}
} else
{
return false;
}
} else
{
return true;
}
}
with this approach will make creating CRUD functions easier. Heres a sample insert function.
public function insert($table,$values,$rows = null)
{
if($this->tableExists($table))
{
$insert = 'INSERT INTO '.$table;
if($rows != null)
{
$insert .= ' ('.$rows.')';
}
for($i = 0; $i < count($values); $i++)
{
if(is_string($values[$i]))
$values[$i] = '"'.$values[$i].'"';
}
$values = implode(',',$values);
$insert .= ' VALUES ('.$values.')';
$ins = #mysql_query($insert);
if($ins)
{
return true;
}
else
{
return false;
}
}
}
heres a quick view on using this.
;<?php;
$db->insert('myDataBase',array(3,"Name 4","this#wasinsert.ed")); //this takes 3 paramteres
$result = $db->getResult(); //Assuming you already have getResult() function.
print_r($result);
?>
EDIT
there are more purist approach to handling database operations. I highly suggest it because handling information is very delicate and should be fronted with many safety measures But it requires deeper php knowledge. Try PDO for php and this article by matt bango on prepared statements and its significance.
I am not sure what keywords to use to search for this answer, its simple but nothing found.
Model are used for sql queries as far as I know. No logic.
So then what about filters?
For example
function getItems($partnerUserId) {
$param = "";
$params = array();
if ($partnerUserId !== '') {
$param = "AND z.x = ?";
$params[] = $partnerUserId;
}
$sql = "SELECT ...
FROM z
WHERE z.a = 1
$param";
return DB::connection($connection)->select($sql, $params);
}
And in real world example there get much more those statements. Is this how model should be
or I should do this logic in controller and then pass filter strings as parameters to the model function?
this is basic layered architecture , construction of query should be done in data mapper or dao classes. if it is some redundant code or complex code, you can create util with static method and call from data mapper layer.
How I can execute a SQL query in CakePHP.
I want to make some like this code
$employees = $this->Employee->find('all');
but introducing my own SQL statment.
Insert into your Model a function that executes your SQL statment,
public function get_employees() {
$sql = 'select * from employees';
$data = $this->query($sql);
return $data;
}
And call this function like this way:
$employee = new Employee();
$data = $employee->get_employees();
In model you can't write model name. Its already detected. Use only
$this->find('all');
Assuming your statement is inside EmployeesController.php
$employeeRows = $this->employee->find('all', array('conditions'=>array('id' => 100)));
if you are in another controller, you have to load the model before the find
$this->loadModel('employee');
if you are in a view, you can write a helper and use raw sql
The cakephp website also offers the following controller logic
$this->Picture->query("SELECT * FROM pictures LIMIT 2;");
I am passing a parameter from model to view like this
Model
class school_model extends CI_Model{
function employee_get($student_id){
$query = $this->db->get_where('students', array('student_id'=>$student_id));
return $query->row_array();
}
}
Controller
function bret($student_id){
$this->load->model('school_model');
$data = $this->school_model->employee_get($student_id);
echo $data['student_gender'];
}
This obviously translates to select * from students where id=id given for example and seen through the browser like http://example.com/env/at/index.php/frontpage/bret/306
I am wondering if the get_where() is suitable if i wanted to have this query
select student_gender,student_has_a_medical_condition from students where (student_gender = 'female' && student_has_a_medical_condition = 'no') LIMIT 40;
Will i need to extend get_where() for it to work?.
First,I suggest reading the excellent documentation for CodeIgniter on the ActiveRecord class.
You don't have to extend get_where() but just use the existing methods to define your query:
function employee_get($student_id){
$this->db->select('student_gender','student_has_a_medical_condition');
$query = $this->db->get_where('students', array('student_id'=>$student_id,'student_has_a_medical_condition'=>'no','student_gender'=>'female'),40);
return $query->row_array();
}
Of course you can pass in the additional parameters to the function so they are not hardcoded, and you can also pass in the desired columns as a paremeter, too. But start with the documentation.