Click to See Complete Forum and Search --> : If you were sent this as part of an application what would you do?


Arc
03-06-2006, 05:46 PM
Hey guys, I need some real help here. I am applying for a job as an OOP PHP programmer. I know how to code in OOP with PHP, but what they are asking for is confusing and I am not sure what I should send to them.

Here is what they are asking for:

"...if you would send me the following: Separation of business logic from display logic. (don't mix classes & HTML) Object oriented code. more than just using $this->function()"


What would you put together and how would you put it together? I am drawing a blank here. I already sent them a full password protected admin area that was all based on OOP design, but apparently that wasn't complicated enough or something.



Any input is appreciated! Thanks!

jkurrle
03-07-2006, 01:00 AM
The way I see it is they don't care about how you display the data. That's something they assume you should know. What they want to know is how you would design, lay out, and implement a business solution.

Examples:
1) Inventory Management
2) Personnel Scheduling
3) Trouble Ticket Management

Sounds like they want to see how you would do the back-end plumbing for a business class app. I'd lay out the database design, then write the code to take advantage of it. Document the code, document the application, document the database, use easy to understand variables, etc. Sounds almost like an ISO 9001 shop.

Best of Luck.

Arc
03-07-2006, 01:25 AM
Thanks for the input. I don't get how I am supposed to keep OOP code and HTML seperate..... I mean in order to manage inventory,for example, you need a front end and the front end is going to have calls to classes...

hrmmm.

MrPotatoes
03-07-2006, 01:39 AM
think smarty ese.

what you do is you have whatever code that you need. it outputs to a tag of some sort. we'll call it $site_name. that site name will be called in a XHTML .tpl file or something like that (htm, html, tpl etc). in there the code would look similar to this:

<html>
{site_name}
</html>

the **** in the curly brackets is defined in your OOP. so it finds the $site_name and what is contained in there and puts it into {site_name} and it would display that.

look up smarty templates. this is what they are talking about. i'm not too keen on it right now (haven't gotten to that integrations yet...) but it's not hard in concept :D

rock out

bpat1434
03-07-2006, 02:06 AM
Arc, if you want to see a really good example of separating GUI from backend, download PHP SUpport Tickets 2.x. The coders (whom I talk to occasionaly) use a factory class with abstraction and such to create the GUI. But they have a very intricate back-end of just data manipulation. So really, if they wanted to change templates, it's a matter of changing one file or set of files that deal with the GUI factory.

I left the project soon after they made people start to pay for it, but version 1.9 was awesome to play around with. 2.0 introduced the OOP style programming and PHP 5 code techniques. It'd be a good basis to give you and idea of what they're looking for as far as separation of HTML and data.

But basically, they want you to show that you know how to do manipulation, and in a much more "general" way with OOP than just using a class. They want to see abstraction, manipulation, dynamics, fluidity, and coding practice. Just do your best and create a simple app that can log people in, do something, and log them out. I'm guessing it doesn't have to be full-featured, but just enough so you do plenty of data handeling, and can show them you've got potential and room to grow.

Arc
03-07-2006, 03:12 PM
Thanks for the input. I am looking at the PHP tickets thing and it seems pretty complex. More complex than anything I've done, so it's a bit over my head as far as the way the whole thing works together. I noticed it was extending other classes, but the class that it was extending were not "included" in the file...How does that work?

As an example of what I sent to them previously was a successError.php file that had success and error functions that would display a message to the user assuming the SQL statement ran properly. It included a navigation class which adds the top and side navigation as well as the footer around the main page.

is this bad coding?



//dbConnectclass.php
class DBConnectClass{

//Connection Variable
var $Connect;

//open connection to database
function DBConnect(){
$Hostname = "localhost";
$Database = "Books";
$Username = "Uname";
$Password = "Pass";
$this->Connect = mysql_connect($Hostname, $Username, $Password) or die(mysql_error()."<div align=center>Sorry, we are currently experiencing technical difficulties, please try again later....</div>");
mysql_select_db($Database, $this->Connect) or die( mysql_error()."<div align=center>Sorry, we are currently experiencing technical difficulties, please try again later.</div>");

}//end DBConnect

//close database connection
function DBClose() {

mysql_close($this->Connect);

}//end DBClose

}//end class DBConnectClass

//---------------------------------------------------------------------------------
//navclass.php

class NavClass{

function TopNav(){
require_once("topnav.php");
}//end TopNav

function SideNav() {
require_once("sidenav.php");
}//end SideNav

function Footer() {
require_once("footer.php");
}//end SideNav

}//end class NavClass

//-------------------------------------------------------------------------------------
///successErrorClass.php

include("navclass.php");


class SuccessErrorClass{


function ErrorMessage($msg){
$nav = new NavClass();
?>
<td valign=top>
<br>
<p><b>Error: <?php echo $msg; ?></b><br>
If this error persists please write us an email by <a href="mailto:name@yourdomain.com">clicking here</a>
</td>
<?php
$nav->Footer();

}//end ErrorMessage

function SuccessMessage($msg,$forward, $forwardWhere) {
$nav = new NavClass();
?>
<td valign="top">
<br>
<p><b>Success:</b> <?php echo $msg; ?>
<br>
<br>
Your are now being forwarded <a href="<?php echo $forward; ?>"><u><font color="#9C5B4C"><b><?php echo $forwardWhere; ?></b></font></u></a> If you are not transferred please click <a href="<?php echo $forward; ?>"><u><font color="#9C5B4C"><b>here</b></font></u></a>
<META HTTP-EQUIV="refresh" CONTENT="3; URL=<?php echo $forward; ?>">
</td>
<?php
$nav->Footer();
}//end SuccessMessage

}//end class SuccessError

//---------------------------------------------------------------------------------------
and they are used like so....
///addBooks.php

include("../checklogin.php");
include("../includes/successerrorclass.php");
include("../includes/dbconnectclass.php");
$con= new DBConnectClass();
$se = new SuccessErrorClass();
$nav= new NavClass();

$nav->TopNav();
$nav->SideNav();

$Submit = $_POST['Submit'];
$AuthorName = $_POST['txtAuthorName'];
$BookName = $_POST['txtBookName'];
$BeenRead = $_POST['chkBeenRead'];

if($BeenRead != 'Yes')$BeenRead = 'No';

if(isset($Submit)){//if form submitted
//connect to database
$con->DBConnect();
//Insert into DB
$insert = "INSERT INTO tblBooks (AuthorName,BookName,BeenRead)
VALUES ('$AuthorName','$BookName','$BeenRead')";
$result = mysql_query($insert);
//close database connection
$con->DBClose();
if (!$result){
$se->ErrorMessage("SQL, Insert error");
}else{
$se->SuccessMessage("Book information succesfully added.", "../index.php", "home");
}//end if
}//end if



If I needed to change the database connection string for say MSSQL I would simply edited that dbConnect.php page and thats it. No need to go thru every page and edit anything.

Could you guys give me some input on what would be a better way to do what I am doing here? A more "OOP" way. I know you have explained it and I sort of get what you are saying, I guess I just need a simple example so I can wrap my brain around it.

Thanks a lot guys!!

Shrike
03-07-2006, 03:51 PM
I think I am going to give alot of criticism here but please don't take it too badly. I'm no expert but I have some things for you to consider.

First up class DBConnectClass.

The immediate thing which springs to mind is that you have hardcoded database connection information in the class. This immediately limits the class to one database. Of course you can make a copy of the file and edit the details, but then you've got two files to maintain instead of one. Why not pass the connection information to the constructor of the class for more portability.

Secondly you have a property $Connect which is only used in one method, and the class doesn't provide any kind of accessor for that property, so your relying on PHP's fallback mechanism. The property is unneccesary.

A very minor niggle is the naming convention. Why DBConnectClass - I already know it's a class. It might seem like nitpicking in the extreme but it's fairly important when you work in a team.

Next NavClass (naming again! :p )

What is the point of this class? It serves no purpose whatsoever other than wrapping require_once(). The files it works on are hard coded so again there is no portability. Really no need for this class to exist at all.

SuccessErrorClass (yeah you guessed it naming)

I think this is the real bone of contention which your prospective employer has. You have HTML intermingled with the class. Whilst this is sometimes unavoidable it is something to avoid as much as possible. As noted a key factor in good design is separation of business logic from presentation. The reason for this is when presentation and logic are intermingled it becomes difficult to make changes to the logic without having an impact on the presentation, and vice versa. Also when working with a team of people - commonly developers and interface designers - it makes sense that they don't clash with each other all the time. There is a technique or design pattern which deals with this problem called Model View Controller. Google knows all about it.

People have already suggested some good ideas on this so I won't go further.

My advice to anyone wanting to write object oriented code is to read as much as possible about inheritance, encapsulation and polymorphism. These are key to object oriented languages and important to have a good understanding of.

By the way inserting $_POST data directly into the database without any sanity checks is sure to make you look bad.

Good luck with the job :)

Arc
03-07-2006, 05:55 PM
Thanks for the input. That's exactly the kind of critism I am looking for. If anyone has any more examples I'd appreciate it.

makeshift
03-07-2006, 06:02 PM
Look at smarty and perhaps some of the sourcecode behind forum software. There is SO MUCH templating going on that its really interesting to look at.

In the end, there is no way you can have 100% separation of html and php (well.. it is possible but you'd be wasting your time more than not). You just want that sweet spot where you can make heavy overhauled design changes with minimal changes to the backend. For example, if there is html in your backend it should just be trivial things like A HREF links or making things bold and whatnot... things that are totally design independent but you dont want to bend over backwards to get them out of the backend.

MrPotatoes
03-09-2006, 10:31 AM
Look at smarty and perhaps some of the sourcecode behind forum software. There is SO MUCH templating going on that its really interesting to look at.

In the end, there is no way you can have 100% separation of html and php (well.. it is possible but you'd be wasting your time more than not). You just want that sweet spot where you can make heavy overhauled design changes with minimal changes to the backend. For example, if there is html in your backend it should just be trivial things like A HREF links or making things bold and whatnot... things that are totally design independent but you dont want to bend over backwards to get them out of the backend.

exactly

Davidc316
03-09-2006, 04:49 PM
Based on the quote you supplied, I wouldn't want to work for him. With respect to you, I think your future employer comes across being somewhat clueless.

If they really wanted to test your knowledge of PHP I think he (or they) should simply check out your CV/refs and perhaps test you in an interview situation by throwing a few PHP related questions at you and maybe even getting you to quickly jot down an algorithm or a few lines of code on Notepad.

As things stand, I think he has failed to clarify what he wants and he seems incapable of constructing meaningful and grammatically correct sentences.

Perhaps you should ask them for some clarification. There's no sin in doing that and I think he (or they) might respect you more for doing so. Let them know that your philosophy, as a PHP developer, is to never commit yourself to a single keystrike unless the client has been absolutely crystal clear on the objectives they wish to achieve.

For all you know there could be dozens of people going for this job. If you get back to them with the kind of brave response that I'm suggesting, I think you will not only win some respect but you'll also separate yourself from the rest of the herd.

All the best!

Shrike
03-09-2006, 06:35 PM
I fail to see what is clueless about the request. Anyone who has worked in the industry for a reasonable amount of time will of come across the notion of separating interface from logic. It's a perfectly reasonable request. As for the grammar, well we are the slacker generation right? Maybe not :)

dream.scape
03-09-2006, 07:19 PM
I agree with Shrike... it is a pretty straightforward request, and n-tier application design is a well proven and effect development method that has been around for quite some time. It is not outside the realm of PHP.

I don't believe he is asking for a full blown application or anything like that... just a simple n-tier design (he says it only needs to be 2-tiers) that demonstrates you know how to work with and create such designs.

By "business logic" he means logic that is in the domain of the business of the application, i.e. application logic or application business logic. "display logic" is logic that is in the domain of the view (or gui if you want to say).

A simple example to show the difference between those 2 types of logic, would be a check register. Calculating the register's balance is business logic. Displaying a negative balance in red would be display logic. Calculating each line of the register is business logic. Displaying the lines in alternating colors is display logic. See the difference? Though, it is not a clear line, and sometimes you come across logic that could fall in either, depending on your perspective.

Actually I think a small and simple check register would be a decent thing to do for the application. He didn't say it has to be super complex; it just has to use n-tier design (can be just 2-tier to be specific).

Davidc316
03-09-2006, 10:01 PM
One of central reasons why the question setter is clueless, I believe, is the fact that they failed to anticipate that the person(s) being asked to do the task would simply jump onto a forum like this an get someone else to work it out for them (not that there's any sin in that of course, but it doesn't help the employer to glean an insight into who the best developer is, I think).

dream.scape
03-09-2006, 10:47 PM
One of central reasons why the question setter is clueless, I believe, is the fact that they failed to anticipate that the person(s) being asked to do the task would simply jump onto a forum like this an get someone else to work it out for them.

There is that risk for any kind of "take home" assignment or application. Further you don't know that they don't know that. Have you talked to them and confirmed that or are you just making **** up now?

Not to mention what you actually said, and I quote, was "As things stand, I think he has failed to clarify what he wants and he seems incapable of constructing meaningful and grammatically correct sentences. "

What he wants is "if you would send me the following: Separation of business logic from display logic. (don't mix classes & HTML) Object oriented code."... really that couldn't be much clearer. It is pretty open ended, but that doesn't make it unclear. If you know what "business logic" means, what "display logic" means, what separation of the 2 means, and what "object oriented code" means, then you know exactly what he wants. If not, then the job will probably be beyond your current skills.

Davidc316
03-10-2006, 11:47 AM
Have you talked to them and confirmed that or are you just making **** up now?

:)

Arc
03-10-2006, 08:39 PM
Hey guys. I didn't realise this would cause any controversy.

The reason I posted here is for the very reason one of you stated (It is very open ended). And I was looking for ideas (Not code).

The thing I already sent them a full password protected admin area that's all OOP, and that wasn't good enough, so that's why I came here for ideas.

Since then I have written a complete mysql wrapper class that does most of the typical things you do with mysql (Basicaly all DML and DDL statements), including error reporting ( last error and all errors in an array). I also wrote a front end that shows the way the class works.

When the lady says, "More than $this->function()" I am assuming they are also looking for use of inheritance and other OOP designs.

So yah, the requirements are very open ended and pretty unclear IMO. If I hadn't already sent them some code then I could see it being open ended, however, now I am still unclear of exactly what it is they want. I am about finished with what I am going to send them, if this isn't god enough then I guess I won't get the job. But as was said they aren't exactly being very clear in what they are looking for.

Weedpacket
03-10-2006, 11:26 PM
I'll offer an observation about tier separation, using DBConnectClass as an example of where they haven't been:

$this->Connect = mysql_connect($Hostname, $Username, $Password) or die(mysql_error()."<div align=center>Sorry, we are currently experiencing technical difficulties, please try again later....</div>");
mysql_select_db($Database, $this->Connect) or die( mysql_error()."<div align=center>Sorry, we are currently experiencing technical difficulties, please try again later.</div>");

(I'm sure the mysql_error() message is purely a development-time measure, so I won't mention it further.)

What would have been more "OOP friendly" than die("<div>...</div>"); would be to call on something more like SuccessErrorClass that, given a message, would construct and output a proper page that fits in with the rest of the site (in fact, it wouldn't construct the page itself, but call on the same code that the rest of the site calls on to generate pages to do the job). It would also do whatever error-handling measures are required (e.g. logging), and then it would terminate the script.

If you were separating display logic from the other layers, then the die(); and certainly the <div> wouldn't appear in DBConnectClass. It's not the job of the database connection class to be producing page content, and especially not ill-formed content like a lonely <div> without the basic infrastructure of an HTML document and strands the user on the Web page equivalent of a desert island (you know, the kind of island with <div align="center">A solitary palm tree</div>).

Arc
03-11-2006, 05:30 PM
Thanks for the input Weed. I am having a realy hard time figuring out how to seperate the HTML from the SuccessError class.

I have extended the Success Error class into my mysql_con_trans class and call it in place of the error code I had before.

Can anyone give me a heads up if this would considered ok? I can't realy see how I can seperate the HTML from this class because it builds the page around itself outputing the message that was sent.

Thanks!

SuccessError Class

class SuccessError{


function ErrorMessage($msg,$email){
require("topnav.php");
require("sidenav.php");
?>
<td valign=top>
<br>
<p><b>Error: <?php echo $msg; ?></b><br>
If this error persists please write us an email by <a href="<?php echo $email; ?>">clicking here</a>
</td>
<?php
require("footer.php");

}//end ErrorMessage

function SuccessMessage($msg,$forward, $forwardWhere) {
require("topnav.php");
require("sidenav.php");
?>
<td valign="top">
<br>
<p><b>Success:</b> <?php echo $msg; ?>
<br>
<br>
Your are now being forwarded <a href="<?php echo $forward; ?>"><u><font color="#9C5B4C"><b><?php echo $forwardWhere; ?></b></font></u></a> If you are not transferred please click <a href="<?php echo $forward; ?>"><u><font color="#9C5B4C"><b>here</b></font></u></a>
<META HTTP-EQUIV="refresh" CONTENT="3; URL=<?php echo $forward; ?>">
</td>
<?php
require("footer.php");
}//end SuccessMessage

}//end class SuccessError


mySQLConTrans Class

include("successerror.class.php");
class mySQLConTran extends SuccessError{

var $con;
var $numRows;
var $result;
var $errorArray = array();
var $lastError;


// Open Database connection ---------
function dbOpen($name,$host,$user,$password){
$this->con = @mysql_connect($host, $user, $password)or die (parent::ErrorMessage("Error Connecting To The Database","john@somedomain.com"));
@mysql_select_db($name, $this->con) or die (parent::ErrorMessage("Error Selecting Database!","john@somedomain.com"));
}//end dbOpen

// Close Database Connection --------
function dbClose(){
@mysql_close($this->con);
}//end dbClose

// INSERT, UPDATE, DELETE, CREATE, DROP etc... --------
function dbCommand($sql){
$this->result = @mysql_query($sql);
if(!$this->result){
$this->lastError = mysql_error();
$this->errorArray[] = mysql_error();
return false;
}else{
return true;
}//end if
}//end dbIUD

// SELECT FROM Database --------
function dbSelect($sql){
$this->result = @mysql_query($sql);
$this->numRows = @mysql_num_rows($this->result);
if(!$this->result){
$this->lastError = mysql_error();
$this->errorArray[] = mysql_error();
return false;
}else{
return true;
}//end if
}//end dbSelect

// Get first row of dbSelect --------
function getFirstRow(){
$firstRow = @mysql_fetch_array($this->result);
return $firstRow;
}//end getFirstRow

// Get last row of dbSelect --------
function getLastRow(){
@mysql_data_seek($this->result,$this->numRows-1);
$lastRow = @mysql_fetch_array($this->result);
return $lastRow;
}//end getLastRow

// Get any row of dbSelect index starts with 0--------
function getAnyRow($rowNum){
if($rowNum > $this->numRows || $rowNum < 0){
return false;
}else{
@mysql_data_seek($this->result,$rowNum);
$anyRow = @mysql_fetch_array($this->result);
return $anyRow;
}//end if
}//end getLastRow

// Get number of rows from dbSelect --------
function getNumRows(){
return $this->numRows;
}//end getNumRows

// Get number of mysql_errors --------
function getErrorCount(){
return count($this->errorArray);
}//end getErrorCount

// Get error array --------
function getErrorArray(){
return $this->errorArray;
}//end getErrorArray

// Get Last mysql_error --------
function getLastError(){
return $this->lastError;
}//end getLastError


}//end mySQLConTran Class -------------------------------