PHP install method in a class what requires database tables/columns - php

I was wondering how does you guys write your classes when they need tables in the database to function or some other things to do before it functions?
Do you use a method to insert the tables in the database or do you write the class to require some columns in a table which can be define at some settings variable?

Whilst the answer to this question is a matter of opinion, I would generally create them in the class constructor (checking whether they exist first or not), however I would allow the user to specify their own names and prefixes to avoid clashes and data loss within their database.
The reason being is that you have total control over how the tables are constructed as opposed to trusting the user to generate them correctly.
This is assuming your class will be used by other people, if it is solely for your own use it is safe enough to assume you are able to build the tables yourself and could remove that overhead from the class.
It also depends what your class is for, if it is a plugin then you should definitely create these for the user so they don't have to touch the underlying code, following any of the database naming conventions of the system your plugin is integrating with.
This is just my personal style and is by no means a standard or necessarily the optimum way.

Related

Virtual private databases with Eloquent

I want to have variable number databases that appear to be separate but are actually in one MySQL database.
These separate instances should be creatable and destroyable inside the application and while normal users work inside a single database instance, the system administrator could see all of them.
This concept seems similar to Oracle's Virtual Private Databases.
I am willing to implement the functionality in Laravel app but I am not sure how to do it.
I would add column instance_id to tables that I want to be instanced and the plain way would be to include something like where('instance_id', Auth::user()->instance_id) in every query, but this is nightmare to add that to every query...
How can I hide that in a neat way so I could either use something or extend improved model class whenever I need a model to be instanced. I want to do it in a way that I could also query the whole table ignoring instancing if I specify that.

A single php file for all forms

I have four forms on my website sending user input to four different tables in my MySQL database. Is it good practice to put all the queries for those four forms in a single php file?
Currently, I have a different php file for each form. Eg. form-abc.html has a abc.php to communicate with the database, form-def.html has a def.php and so on.
Since the mysqli connection in all these forms is going to be the same, I was wondering if it is possible to call the relevant function/ query from a php file containing all the queries/functions? And if it is possible, how?
On balance it is not good practice to put the code in a single file, particularly if the four queries are not obviously related in terms of their purpose, but it would also be poor design to have each file containing the code to connect to the database, and also to be hand crafting the query strings.
You should seek to factor out common code to a utility library, with your starting point being to have a single library function that returns a connection to the database. Changing connection details, the name of the database etc. then requires a single change rather than four, and so reducing the chances of a mistake. Your four files should also not need to know how to connect to the database, and removing the code achieves that.
Rather than hand crafting the queries, where there is a chance of failing to properly escape data and where you will end up writing more code than is necessary as well as locking yourself to a particular database type, you should aim to have library routines to help with this. PHP has some libraries already, or you could develop your own that are potentially better suited for the job.
Very broadly, you may end up with code such as this:
<?php
include_once "db_utils.php";
$db = DB::get_instance();
if (isset($_POST['form_submitted'])) {
// Validation etc.
$customers = $db->table('customers');
$customers->insert(array('name' => $_POST['name'], 'email' => $_POST['email']));
// ...
}
The include would include your database utilities, providing in this case a class called DB, and a table class. get_instance() would be a static method to provide database instance that encapsulates a connection. We'll assume that it knows how to obtain connection information, so not needing that to be provided to the method. The table() method would provide an instance of a database table that would know how to perform operations on a database table. The insert() method on a table instance would take an array of key/value pair data, escape the value of each item and do the insert.
Keeping the queries with the files that need them should in this case ease maintenance.
An alternative approach to your entire site would be to use a framework. In such a case, the business logic, database management and rendering code would be separated, which for non-trivial systems is generally a desirable aspiration. If one cobbles a system together with that in mind in an ad-hoc way, this could quickly lead to an unmaintainable system, with developers struggling to find the relevant code that plays a part in a request, however a framework would impose a structure through naming and layout conventions that would largely alleviate that.
For where you are now though, just aim to identify duplicate code, factor that out, look for some database libraries so that you are not hand crafting queries (if you are right now), and keep your system simple.

multiple databases with same structure

What is the best way in doctrine2 to deal with different bases but with the same schema. Currently I
generate entities separately for every database, adding namespace and name of database to every metadata object, putting them in the different namespaces (XXX\Base\EntityClass), but with the same alias
create one EntityManager per base (even if they are sharing same connection)
create a proxy which passes calls to multiple EntityManagers and collects responses
merge responses in one output
Is there simpler way of dealing with multiple bases in doctrine2 ?
I can't answer for doctrine2, but I'm doing this in C#.
One set of entities, with strong names and strong types, defined in terms of what the rest of the application needs. This maps the schema, but isn't tied to either database.
One facade, the knows which database you're using at the moment, and directs requests to one of two...
Separate data access namespaces, that handle a common set of operations, and populate results into the single set of entities, which are returned to the requestor through the facade.
Static code generators, based on reading the scema from the database catalog, are useful. You may want to pick one as a model, if you can infer everything you need to know about the other database.
Dynamic code generators are also useful, for inserts, updates, where clauses, etc.
Invest some time in a framework to support all of this. Decide whether you need to keep metadata at run time, and whether it's primarily to support queries or change operations. Provide a common method for extracting data from results sets for either database, so that you can get strongly named and typed result sets back to your application without regard to the underlying database.

Approach to mapping dictionary database tables to models in MVC

lacking a fellow programmer to talk over the right approach for my problem, I decided to ask you. What is your preferred approach of mapping dictionary tables to a model in MVC paradigm, regardless of the MVC framework / environment you are using?
My problem is I have a couple of database tables that only serve as dictionaries and are related to other tables as foreign keys. A good example would be a table request having a status_id where statuses are kept in a separate status table.
Now, the latter table needs to be mapped to a model on the code-side of the application. I can either:
Define all the statuses as constants so they can be referenced in the code without poking those dreaded 'magic numbers' here and there. However, any change to the dictionary (database-side) would require a code modification.
Omit the `status` table at all and just define meaningful constant to be used across the code. Pros: one place to rule them all. Cons: all changes require diving into the code, now the database features 'magic numbers' not really being foreign keys
Try to translate statuses into the model automagically, adding a field like 'const_name' to the 'statuses' table and them creating the constants on the fly while loading the model. This one seems to have the most sense for me.
Would you mind to share your usual approach to this issue?
Best,
Bartek
If it's just going to be a set of constants that are contained in the database instead of code, you could have a static class load the status constants for everyone else to use. That way there's no duplication between db and code, and no magic numbers.
edit: since it's a static class, you could have it lazy load the constants. Don't hit the database until the first time someone asks for a status value.
I'd say if you going to change it often it's better to go with table. Otherwise static class is fine (for example no point having table to store sex, or list of states).

How to refactor better model functions in CakePHP?

I'm reading programming best practices and it is said that when creating a function we should make it do a only single specific task.
I got model functions that retrieves data and it's related data. Example:
$this->Student->StudentAssignments();
Currently this function retrieves the student's assignments plus the question for each assignment and data about the student. I use them all. My dilemma is if I try to make separate functions that retrieves the related data (student and question datas) it's taxing since I'm producing more calls to the DB.
What would you guys suggest?
Something to keep in mind when doing this sort of refactoring...
I typically will have a Model->getSomethingAndSomethingElse functions in my models.
These functions are public and meant to be called as a substitute for doing complicated (or any) find calls from the Controller.
What I will usually do is then build up a small collection of private functions in the model.
In your case I might have something along the lines of...
Student->getStudentAssigmentsWithQuestions
that then calls some private functions i.e.
Student->getStudent which might call Student->joinStudentAssignment which in turn might call Assignment->joinAssignmentQuestion etc.
The double underscore prefixes have been removed since markdown wants to bold things because of them. If you are using php5 the underscores aren't really important anyways as long as you use the "private" or "proteced" keywords.
Basically I use the public method as a container for a group of very specific query building or association building private functions within the models. This allows me to have an api that has complex data returned, but I build the query or the result set (depending on the type of data, relationships involved or query complexity) from small pieces - that can ideally be purposed and used in more than one public function call.
I think you're doing fine. But you should reconsider renaming your function to
$this->Student->getStudentAssignmentsWithQuestions
Or whatever you think fit. I think one should try to do as few calls to the database as possible (I assume you're performing a join somewhere in there), instead of fetching each set of elements by specific methods. This can lead to the fact that you'll get more methods (and therefore have to write some more tests), but I think this is the right way to do it.
To defend the design argument:
Your method does just one single task; it fetches student's assignments with each assignment's questions.
No, if you're strictly concerned about code refactoring you should break down that blob into simpler functions that perform a single task as you said. Yes, you will hit more your database but considering how easy is to work with caching in cakephp, performance should not be an issue. And if it is, then you shouldn't worry about code refactoring at this point.

Categories