I'm making a school project on which I have to create a web app based on a Oracle database, and after testing some php frameworks I'm currently using CodeIgniter. I'm pretty new to the MVC and php, so excuse me if I make any mistake..
I understand that (beeing a MVC framework), on my Model, it's possible to run queries like
$query = $this->db->query("SELECT * FROM tablename");
But on my studies I read that it's good practice to, everytime we want to run a query/insert/etc, we should open a connection and end it after making the operation. I believe that's supposed to prevent 'inconsistencies'..Something like
<?php
$conn = oci_connect('user', 'pass', 'dbname');
$query = 'select * from tablename';
$stid = oci_parse($conn, $query);
oci_execute($stid, OCI_DEFAULT);
while ($row = oci_fetch_array($stid, OCI_ASSOC)) {
foreach ($row as $item) {
echo $item." | ";
}
echo "
\n";
}
oci_free_statement($stid);
oci_close($conn);
?>
Is that so? If it is, then the that command I'm making on my Model is correct or not?
I can only think of running this php script on a view.php file but by doing so I guess I'm not implementing the MVC 'concept', just calling this kind of php script...right?
I'm getting the results with the two method, but im not sure which's the best way to do it..
Thanks in advance!
You don't have do such loads of work. It's MVC. Mode-View-Controller . Everthing is all done and managed. You have to provide the connection details in database.php file kept in config folder. And ci will automatically make a connection with database.
And call these all queries in model. Make a function in model for your requirement and call it in controller. And, hence you can get your result in controller and pass it to the view.
Since you are using the Codeigniter MVC framework then adding your own database routine would definitively be an overkill and not good practise. CI has a well developed and secure DB library and using CI Active record syntax greatly simplifies db queries. So look into this and learn the great benefits of a thought trough framework.
http://ellislab.com/codeigniter/user-guide/database/active_record.html
Related
I am working with a database and trying to create a theatre booking website where the customers can input their details to perform an order, I want to separate queries for the customer details and performance details etc. Could I use functions to separate it out? Or am I going the wrong way about it? this is what I have so far.
<?php
$connectdb = mysqli_connect("host", "username", "password", "database")
or die("Error ".mysqli_connect_error($connectdb));
function customerDetails(){
mysqli_query($connectdb, "QUERY GOES HERE");
}
mysqli_close($connectdb);
Many Thanks!
The problem here is that the variable $connectdb is defined in the global scope (outside any function), and to use it inside a function you need to import it using the global keyword:
function customerDetails(){
global $connectdb;
mysqli_query($connectdb, "QUERY GOES HERE");
}
Creating functions to retrieve data is good mostly because it abstracts the code and makes it re-usable. That is: you can call customerDetails() in more than one page, and if one day you want to switch from MySQL to MongoDB (for example), you just need to update that function. It's not really for performance reasons at runtime (actually, without a function it should be slightly faster), but it makes development much more easy and efficient (and cost-effective).
I am currently working on a CMS and am learning how to use OOP.
My question is: How do I take variables set in a mysql database and use them on my website?
Lets say I have 2 columns, one called var_name and var_content.
How would I use it so that $var->sitetitle; echos out whatever it matches up to in my database?
I don't know what this is called, if anyone could lead me in the right direction, I appreciate it!
Right now, I have this:
require_once("classes/database.class.php");
$database = new database();
$database->set_value('sitevariables', $database_prefix . "sitevariables");
$database->set_value('host', $database_host);
$database->set_value('pass', $database_pass);
$database->set_value('user', $database_user);
$database->set_value('table', $database_table);
I wanted it so I could use $database->host to get my mysqli server. It's basically the same thing as I want to do, except it takes from the database to get and set the values
you can define a function to get variables, once your database connection is set up (I sadly not think it is possible to query the database for credentials to connect to that vary database. kind of spiraling thing there.)
this takes into account that var() is a member function of your database() class. Since I don't have your database class, I don't think the way I'll query the database is like yours, but you will be able to fix that.
function var($var_name) {
$stmt = $this->query('SELECT var_content FROM variables WHERE var_name=?');
$stmt->execute(array($var_name));
return $stmt->fetch(PDO::FETCH_COLUMN);
}
$sitetitle = $database->var('sitetitle');
I have recently started using codeigniter and I am a bit stuck as it is all rather new to me.
I use to have a config file with database conection and this on it:
$qset = "select * from re_settings";
$rset = mysql_query($qset) or die(mysql_error());
$aset = mysql_fetch_array($rset);
and this would allow me to pull words from database by simply putting this on the site
<?=$aset['SiteTitle']?>
How can I do this in codeigniter? Do I need to have a controller to do this or is it something much simpler than that.
You'll need to become familiar with the concepts of MCV which is how Codeigniter is built on and your ORM framework.
There's a bunch of helpful resources on http://tutorialcodeigniter.com/ or the official docs http://ellislab.com/codeigniter/user-guide/database/examples.html
as an example
$query = $this->db->query('SELECT name, title, email FROM my_table');
foreach ($query->result_array() as $row)
{
echo $row['title'];
echo $row['name'];
echo $row['email'];
}
I strongly recommend to use Datamapper along with CodeIgniter.
You will be surprised on how it is easy to work with your MySQL database.
Say goodbye to "mysql_fetch_array" 's and such.
Have a look : http://datamapper.wanwizard.eu/pages/getadvanced.html
I have a website with lots of PHP files (really a lot...), which use the pg_query and pg_exec functions which do not
escape the apostrophe in Postgre SQL queries.
However, for security reasons and the ability to store names with
apostrophe in my database I want to add an escaping mechanism for my database input. A possible solution is to go
through every PHP file and change the pg_query and pg_exec to use pg_query_params but it is both time consuming
and error prone. A good idea would be to somehow override the pg_query and pg_exec to wrapper functions that would
do the escaping without having to change any PHP file but in this case I guess I will have to change PHP function
definitions and recompile it which is not very ideal.
So, the question is open and any ideas that would
allow to do what I want with minimum time consumption are very welcome.
You post no code but I guess you have this:
$name = "O'Brian";
$result = pg_query($conn, "SELECT id FROM customer WHERE name='{$name}'");
... and you'd need to have this:
$name = "O'Brian";
$result = pg_query_params($conn, 'SELECT id FROM customer WHERE name=$1', array($name));
... but you think the task will consume an unreasonable amount of time.
While it's certainly complex, what alternatives do you have? You cannot override pg_query() but it'd be extremely simple to search and replace it for my_pg_query(). And now what? Your custom function will just see strings:
SELECT id FROM customer WHERE name='O'Brian'
SELECT id FROM customer WHERE name='foo' OR '1'='1'
Even if you manage to implement a bug-free SQL parser:
It won't work reliably with invalid SQL.
It won't be able to determine whether the query is the product of intentional SQL injection.
Just take it easy and fix queries one by one. It'll take time but possibly not as much as you think. Your app will be increasingly better as you progress.
This is a perfect example of when a database layer and associated API will save you loads of time. A good solution would be to make a DB class as a singleton, which you can instantiate from anywhere in your app. A simple set of wrapper functions will allow you to make all queries to the DB go through one point, so you can then alter the way they work very easily. You can also change from one DB to another, or from one DB vendor to another without touching the rest of the app.
The problem you are having with escaping is properly solved by using the PDO interface, instead of functions like pg_query(), which makes escaping unnecessary. Seeing as you'll have to alter everywhere in your app that uses the DB, you may as well refactor to use this pattern at the same time as it'll be the same amount of work.
class db_wrapper {
// Singleton stuff
private $instance;
private function __construct() {
// Connect to DB and store connection somewhere
}
public static function get_db() {
if (isset($instance)) {
return $instance;
}
return $instance = new db_wrapper();
}
// Public API
public function query($sql, array $vars) {
// Use PDO to connect to database and execute query
}
}
// Other parts of your app look like this:
function do_something() {
$db = db_wrapper::get_db();
$sql = "SELECT * FROM table1 WHERE column = :name";
$params = array('name' => 'valuename');
$result = $db->query($sql, $params);
// Use $result for something.
}
In the xdebug code coverage, it shows the line "return false;" (below "!$r") as not covered by my tests. But, the $sql is basically hard-coded. How do I get coverage on that? Do I overwrite "$table" somehow? Or kill the database server for this part of the test?
I guess this is probably telling me I'm not writing my model very well, right? Because I can't test it well. How can I write this better?
Since this one line is not covered, the whole method is not covered and the reports are off.
I'm fairly new to phpunit. Thanks.
public function retrieve_all()
{
$table = $this->tablename();
$sql = "SELECT t.* FROM `{$table}` as t";
$r = dbq ( $sql, 'read' );
if(!$r)
{
return false;
}
$ret = array ();
while ( $rs = mysql_fetch_array ( $r, MYSQL_ASSOC ) )
{
$ret[] = $rs;
}
return $ret;
}
In theory, you should be better separating the model and all the database related code.
In exemple, in Zend Framework, the quickstart guide advise you to have :
your model classes
your data mappers, whose role is to "translate" the model into the database model.
your DAOs (or table data gateway) that do the direct access to the tables
This is a really interesting model, you should have a look at it, it enables you to really separate the model from the data, and thus to perform tests only onto the model part (and don't care about any database problem/question)
But in your code, I suggest you to perform a test where you have the dbq() function to return false (maybe having the db connexion to be impossible "on purpose"), in order to have full code coverage.
I often have these kind of situations, where testing all the "error cases" takes you too much time, so I give up having 100% code coverage.
I guess the function dbq() performs a database query. Just unplug your database connection and re-run the test.
The reason you have trouble testing is that you are using a global resource: your database connection. You would normally avoid this problem by providing your connection object to the test method (or class).