I am creating a site where different account types will be shown a different version of each page. I have it working, but my question is in terms of speed / "best practices". Which of the following (or something completely different) would be the best way to do this?
Option 1. Break each account type into individual sections of the file:
if($accountType == "type1"){
//All lines of code for the account type1 page
}
elseif($accountType == "type2"){
//All lines of code for the account type2 page
}
elseif($accountType == "type3"){
//All lines of code for the account type3 page
}
Option 2. Break each account type into sections of the file using include files:
if($accountType == "type1"){
//this file has all of the code for account type1 page
require('includes/accounts/type1/file.php');
}
elseif($accountType == "type2"){
//this file has all of the code for account type1 page
require('includes/accounts/type2/file.php');
}
elseif($accountType == "type3"){
//this file has all of the code for account type1 page
require('includes/accounts/type3/file.php');
}
Option 3. Use lots of conditional statements throughout the file to generate the page for each account type:
if($accountType == "type1"){
$result = mysql_query("//sql statement for account type1");
}
elseif($accountType == "type2"){
$reslut = mysql_query("//sql statement for account type2");
}
elseif($accountType == "type3"){
$result = mysql_query("//sql statement for account type3");
}
while ($row = mysql_fetch_array($result)) {
$variable1 = $row['variable1'];
if($accountType == "type1"){
$variable2 = $row['type1Variable2'];
$variable3 = $row['type1Variable3'];
}
elseif($accountType == "type2"){
$variable2 = $row['type2Variable2'];
}
elseif($accountType == "type3"){
$variable2 = $row['type3Variable2'];
}
$variable4 = $row['Variable4'];
}
echo "The variables echoed out are $variable1, $variable2";
if($accountType == "type1"){
echo ", $variable3";
}
echo "and $variable4";
//the rest of the file to follow in the same way
Basically it comes down to this:
Option 1: the file is 1000 lines of code.
Option 2: the file is 30 lines of code, and each include file is between 250-350 lines of code.
Option 3: the file is 650 lines of code. It is less because some of the code can be 'shared' between all three account types.
Which option would be the fastest / "best practice"? I am leaning toward option 3 because overall file size would be smaller, but there are a lot more conditional statements with this option (option 1 and 2 only would have three conditional statements, whereas option 3 would have 40 for example). Does having this many more conditional statements make the file process slower? Is there actually any difference between option 1 and option 2 (does separating the blocks of code into include files mean that it will only load one include file per account type? Or does php load all three files and just choose the proper one?)?
Thanks for your help!
In terms of efficiency, Option 3 would be the slowest as it would have more conditional-checks than any other - however, the speed would be very (very) negligible.
To define the "best practice" would be impossible - it really comes down to "what will be the easiest for you and who-you-work-with to maintain". If, down the road, you have to make massive changes to the code but only for $accountType == "type2", do you want to go through a ton of spagetti code (Option 3), or a bit more separated-into-blocks (Option 1), or just open the specific file for that type (Option 2)?
In my personal opinion, even without using OOP/MVC-framework practices, I would recommend Option 2. Splitting each individual type into their own separated files will save you a lot of headaches in the future if you need to update anything. You can even merge certain parts - for instance, if all three types have one "block" that has all of the same look & feel, you can define that in it's own include and include it in all three of the types'-files.
Please, toss version 1 out of the window, will you! Its very sensitive for errors, and mega files are not really handy.
Myself, I use option 2, but I am not sure if it has to do with the lesser code part. I found it easier to create seperate files for each term, so data doesnt get mixed up. Next to that, its easier to modify. Version 3 is sensitive mxiing up data if you dont look out, and I tried to avoid that. So I personally would pick and still picked in my work version 2.
In terms of performance I don't see much difference between any of the options.
Regarding best practices, I would suggest you go for option 2 which is in my opinion the most maintainable, since you get to keep things concerning each type of user separate and within their own bounds.
If you want to reuse code between the pages, you can still create controls for the shared code that can be encapsulated.
Option 1 sounds like having a huge file where it's hard to find things when you want to modify and you have to be concerned about not modifying stuff for other account types.
Option 3 is IMHO the worst since you get awful spaghetti code and in order to find out what is shown to each account type implies having to go through all of the code.
Related
I recently had a job to optimize a client's website that contains an extremelly cumbersome form in a client's website. I want to optimize it, but I don't quite know where to start.
The website is a "service" database. This database has a special form that allows to send a email to all service providers of a specific type, depending on 2 filters: Location and Service Category. The purpose of this is to ask for a price for a job to several service providers (for example "I need a job in my house, my sink needs replacement, what is the price of that job, etc etc" and it would send an email to several "plumbers" in that location so they would answer and find the cheapest/best one).
So, we have several "if" conditions on a php script that have all combinations with a email list. Here is a snippet of the code:
<?php
if(($sendLocal == "cascais-oeiras") && ($sendCat == "canalizadores")){$mailToList = "email1#gmail.com, email2#gmail.com, email3#gmail.com, email4#gmail.com";}
else if(($sendLocal == "cascais-oeiras") && ($sendCat == "eletricistas")){$mailToList = "email1#gmail.com";}
else if(($sendLocal == "cascais-oeiras") && ($sendCat == "pintores")){$mailToList = "email1#gmail.com, email2#gmail.com, email3#gmail.com, email4#gmail.com, email5#gmail.com";}
...
?>
This extends for a several lines (about 480), because there are about 13 locations ($sendLocal) and 36 service categories ($sendCat). The emails are hardcoded in the script, and managing them is a huge hassle.
Now, I don't need a full script coded, I just want some guidance on where to start and what method to use. I need a way to cross 2 variables (in this case, location and type) and it would return me the ones that only exist in both.
Is there a better way to do this without using a 500 "if" line list? I have no problem coding it from scratch, or using another language/script altogheter.
Thank you.
I would define an array, and then get the addresses from the array. See the example below.
It would, of course, be even better if you would store the addresses in a database (sqlite, mysql, whatever), this way you don't need to edit a piece of code (which is error-prone & comparatively difficult) every time an address needs to be added/removed/changed.
<?php
$lists = [
'cascais-oeiras_canalizadores' => [
'address#example.com',
'moar#example.com',
],
'cascais-oeiras_eletricistas' => [
'address#example.com',
'moar#example.com',
],
# ... and so forth
];
# Note you don't *need* to have $lists hard-coded here, obviously, you could
# also get it from somwhere else, like, read it from a database or text file.
$key = "{$sendLocal}_{$sendCat}";
if (!isset($lists($key)) {
print('No such list');
exit(1);
}
$mailToList = implode(', ', $lists);
Purely hypothetical at this point, no code yet. Trying to figure out the best way to do this. We are company "A" and we have two partners, company "B" and company "C". On a sign up form, we collect data and then pass it on to either partner "B" or parnter "C" - this part is good to go and working fine. I do this with ajax on the front end and a cURL processor on the back end so no one leaves our site and just post the data directly to the partner's form.
Unfortunately due to partner "B" and "C"'s required data the forms we post to are different and we have to have 2 separate html form files, one for each partner. The problem is that we need to do this all from one URL, not a separate one for each partner.
I would guess we would use a 'handler' page that has the specific url - http://www.example.com/parterForm.php
Then in the 'handler' page we would make the switch serve the correct content. I need a way to evenly split who we send data to. I'd like to do the switch on a very granular, MS level for example:
if the time = 0-500 ms - serve Parter B page;
if time = 501-1000ms -serve Partner C page;
all done within the 'handler' page - calling the forms as php includes?
I realize this is not a specific code question and I aplogize, this is something I've never done before and am trying to figure out how to do this. I'm a Creative Director btw who codes, no other resource avail.
thanks.
Hmm, yes, you could do that. That would work reasonably well, in fact. The important thing is to make sure the form goes to the right partner. You could use $_SESSION for that, or check which fields were sent and deduce from that which partner was chosen.
For example:
if( fmod(microtime(),1) < 0.5) include("forms/partner1.php");
else include("forms/partner2.php");
Then when submitted:
$partner1fields = array("name","email","country","dateofbirth");
$partner2fields = array("name","address","postcode","ethnicity");
// the above are examples - they should correspond to the $_POST keys you expect
// now check if they match. Array equality depends on order, so sort first
$postkeys = array_keys($_POST);
sort($postkeys);
sort($partner1fields);
sort($partner2fields);
if( $postkeys == $partner1fields) { /* submit to partner 1 */ }
elseif( $postkeys == $partner2fields) { /* submit to partner 2 */ }
else {
echo "<p>Given keys did not match either partner</p>";
echo "<p>POST keys: ".implode(", ",$postkeys)."</p>";
echo "<p>Partner 1 keys: ".implode(", ",$partner1keys)."</p>";
echo "<p>Partner 2 keys: ".implode(", ",$partner2keys)."</p>";
echo "<p>Please report this error to the site administrator.</p>";
exit;
}
First, by MS I assume you mean the latency between client and server?
Use javascript to either load a tiny image from the server or make an ajax call that gets one char or something and time this. For testing you'll need to do some real pings and adjust your js time to reflect the ping round trip. For example, if the js time to load the image is 500ms but ping time is only 80ms then maybe divide by 6 for the result. This will never be very precise as the client and the server both have processing overhead. Make sure to echo no cache headers or past expire times with the image or ajax response.
Easy, if time <= 500 redirect to form A, if time > 500 redirect to form B or use ajax to load them up.
I wanted some suggestions from someone with experience in php.
I am making a website in php which will have 4 kinds of users :
1. guest(unregistered),
2. registered,
3. registered with special privilages,
4. admins
So the same page will be visible differently to all four of them.
Right now I am doing that by using if conditions.
In every page, I am checking the role of the user and then using many if statements to display the page accordingly.
It makes the code very big and untidy and I have to check conditions again and again in all the pages.
Is there a better way to do this?
How is this done in big professional websites?
Extended Question:
What is the most optimal way to do the same using a MVC framework like kohana 3.1? Does it have anything to do with acl?
It really depends on what you need.
For example if the page has big part that change completely, what I would suggest is to create different templates and include them depending on their "permissions"
$permission = $_SESSION['type_user'];
include '/path/to/file/with/permission/'.$permission.'/tpl.html';
and have something in the page similar to
<?php
//inside include.php you have the line similar to
//$permission = isset($_SESSION['type_user']) && $_SESSION['type_user']!=''?$_SESSION['type_user']:'common';
require_once '/mast/config/include.php';
include '/path/to/file/with/permission/common/header.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_1.html';
include '/path/to/file/with/permission/common/tpl_2.html';
include '/path/to/file/with/permission/'.$permission.'/tpl_3.html';
include '/path/to/file/with/permission/common/footer.html';
?>
if the script is full of small parts like "show this text", or "show this button", you can create a function that will check the permissions for you
<?php
function can_user($action, $what){
switch($action){
case 'write':
return $your_current_if_on_what;
break;
case 'read':
default:
return $your_current_if_on_what;
break;
}
}
?>
and the template will look like:
[my html]
<?=can_user('read','button')?'My Button':''?>
[my html]
As a rule of thumb, if a piece of code is used more than 2 times, it needs to be put in a function/file separately, so if you have many "IFS" you need to create a function
I'm working on a patch to submit to the Registration Code module for Drupal. In short, is there a more efficient way to write the code below?
if (module_exists('regcode_voucher')) {
$cnfg = variable_get('regcode_voucher_display', array('regform' => 'regform'));
if (empty($cnfg['regform'])) {
return;
}
}
It seems like I should be able to reduce it to one if statement with && combining two conditions, but I haven't found the syntax or the necessary php array function that would allow me to do that.
In case some context helps, the regcode_voucher sub-module allows users to enter their registration code on the user edit page. On our sites, after a "beta" period, we want to simplify the registration form by removing the registration code field; but we'd like users to still be able to enter the code on their account edit page. The code above is part of a patch that allows the regcode's hook_user changes to be bypassed.
Code looks like good, what efficient do you want? Little changes may be:
if (module_exists('regcode_voucher')) {
$cnfg = variable_get('regcode_voucher_display', null);
if ($cnfg) {
// do your actions
}
}
And I don't recommend to merge if..., code should be clear and simpler to understand. If you merge these for optimizing, you win "tiny" milliseconds for real-live processors, but lost your clean code.
Why are you returning an array from variable_get if the variable is not found? variable_get will always return a string or a serialized array (that needs to be unserialized). If I'm missing something, you can use array_key_exists('regcode', variable_get(...)) to check for the array key.
This should work... note returning "false" from variable_get as a default if the variable is not found, which will cause the if conditions to not match. I personally find this more readable than nested if statements (for 3+ conditions I'd nest, though).
if( module_exists('regcode_voucher') && variable_get('regcode_voucher_display', false) ) {
// stuff
}
The code below ensures that when a user accesses control panel, they are ran through a quick verification process to validate what their entities are. For instance, if a user is level 1 they are only given access to video feed which means nothing else is available to them.
When I look at the code though, I can see video feed being called when case 1 and 3 are called. I would possibly enjoy an alternative to make the code more efficient.
I was told a possible array could make things a little easier but then again this is faster.
switch ($_SESSION['permission']) {
case 1: // Level 1: Video Feed
include ("include/panels/videofeed.index.php");
break;
case 2: // Level 2: Announcements / Courses / Teachers
include ("include/panels/announcements.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
break;
case 3: // Level 3: Announcements / Video Feed / Courses / Teachers / Accounts / Logs
include ("include/panels/announcements.index.php");
include ("include/panels/videofeed.index.php");
include ("include/panels/courses.index.php");
include ("include/panels/teachers.index.php");
include ("include/panels/accounts.index.php");
include ("include/panels/log.index.php");
break;
case 4: // Level 4: Teachers
include ("include/panels/teachers.index.php");
}
It's fine the way it is. I think you don't mean "efficiency" when you refer to the "repeated" includes. You mean you could compact your code by using the switch fall-through.
While this might make your code smaller, it has no significant impact of efficiency (the time the script takes to run) and it will actually make the code harder to read. Leave it be.
Frist you may run better if you use require_once if its possible.
The second point is to shorten the url it seems that its every include the same.
Maybe try to use it in a function for example:
$permission_id = $_SESSION['permission']
function requireModule($moduleName, $path = 'include/panels/') {
$moduleName .= '.index.php';
require_once($path . $moduleName);
}
// if you want you can add an arry for it:
$permissionModules = array(
array('videofeed'),
array('announcements', 'courses', 'teachers'),
array('announcements', 'courses', 'teachers', 'accounts', 'log', 'videofeed'),
array('teachers')
);
// now we can put it in a more effectiv way
if(array_key_exists($permission_id, $permissionModules)) {
foreach($permissionModules[$permission_id] as $includes) {
requireModule($includes);
}
}
Wrong ? Correct me!