I want to get some advice of using PHP OOP.
For example I'm createing some PHP/MySQL code using OOP and I need to output the code, how to do it?
I might have been bit confusing, I will show you all the code and you tell me if I do it right:
index.php
<?php
require_once CLASSES."Pages.Class.php";
$obj = new Pages;
if (isset($_GET['page'])) {
$obj->setPage($_GET['page']);
echo $obj->getPage();
} else {
echo $obj->getFrontPage();
}
?>
Pages.Class.php - one function from it
public function getDatabasePage() {
global $conn;
$sql = "SELECT * FROM pages WHERE page_seo_title = '$this->pageId' LIMIT 1";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
?>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="well">
<div class="page-head">
<?php echo $row["page_title"]; ?>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="well">
<div class="page-content">
<?php echo $row["page_content"]; ?>
</div>
</div>
</div>
<?php
}
} else {
echo "0 results";
}
}
So basiclly the question is: Where do I need to put HTML code?
In the index.php file or in the pages.class.php file?
How to do this right? Maybe I can get some links with documentation about this from you :) ..
Thanks.
btw - code is an example, not fully done. Just as example - I know it's not right as it is :D
In your Pages class, create a separate method that outputs HTML and does only that; the DB-related logic should be in another method or (preferably) in a totally separate class.
class Pages {
public function __construct(){
//Object initialization logic comes here
}
public function getOutputHTML($resultOfQuery = ''){
return "<div> Your html </div>";
}
}
Other class file only for DB access , just pass parameter and get result as Database result.
class DB {
public function insertMethod($table,$fields,$where){
//Your logic
}
public function updateMethod($table,$fields,$where){
//Your logic
}
public function deleteMethod($table,$fields,$where){
//Your logic
}
public function selectMethod($table,$fields,$where){
//Your logic
}
}
Instantiate DB class like $dbObj = new DB();
Then you can access DB methods like $resultQuery = $dbObj.selectMethod('users');
So you can pass the $resultQuery result to other method like : $objPages = new Pages();$objPages.getoutputHTML($resultOfQuery); . It separates the Database and HTML logic/functionality.
I recommand you to use OOP with MVC so there will be templating system like Smarty,Blade etc.
Related
I have a page called index.php and inside that php i have the function of CRUD and my problem is that how can i separate the php code to html and put it in a class..please help me..
here's the php and html code i want to separate
<label class="Land_Type">
<span>Land Type</span>
<?php
include_once 'dbconfig.php';
$sql = "SELECT Land_Type_Name FROM land_type";
$stmt = $DB_con->prepare($sql);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($stmt->rowCount() > 0)
{
?>
<select name="Land_Type">
<option selected="selected" value="">---</option>
<?php
foreach ($results as $row)
{
?>
<option value="<?php echo $row['Land_Type_Name']; ?>"><?php echo $row['Land_Type_Name']; ?></option>
<?php
}
?>
</select>
<?php
}
?>
</label>
and here is my class
<?php
class crud
{
private $db;
function __construct($DB_con)
{
$this->db = $DB_con;
}
public function login($uname,$upass)
{
try
{
$stmt = $this->db->prepare("SELECT * FROM users WHERE user_name=:uname LIMIT 1");
$stmt->execute(array(':uname'=>$uname));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() > 0)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['user_session']))
{
return true;
}
}
Use a design pattern/architecture like MVC (Model-View-Controller) There's a lot of information to be found about this on the internet and on SO. Have a look at this question and this one for a good start.
Regarding seperating PHP from HTML: the easiest way is to use an existing template engine. Smarty is a very popular one and easy to use.
The important thing is to seperate your business logic. A class should have only one responsibility, which is called the single responsibility principle. In your example, your database class is doing 2 things: it contains the database logic (executing queries) and handling your login system. You should attempt to seperate these.
These things can be pretty confusing in the beginning. My advice is to use a MVC framework (many exist for PHP like codeigniter, cakephp,...) to understand the concepts.
I want to use a variable inside an HTML-String of another PHP-File template.php in my PHP-File constructor.php.
I´m searched on Stackoverflow for a workaround to include the content of the other PHP-File. I included the following code into constructor.php because its known to be more safe instead of using file_get_contents(); Source:
function requireToVar($file){
ob_start();
require($file);
return ob_get_clean();
}
The rest of constructor.php looks like this:
...
$sqli = mysqli_query($mysqli, "SELECT ...");
if(mysqli_num_rows($sqli) > 0){
$ii = 0;
while ($row = $sqli->fetch_assoc()) {
$ii++;
if($row['dummy']=="Example"){
$content.=requireToVar('template.php');
...
The template.php looks like this:
<?php echo "
<div class='image-wrapper' id='dt-".$row['id']."' style='display: none;'>
...
</div>
"; ?>
The constructor.php doesn´t recognize the var $row['id'] inside the string of template.php as its own variable and also doesn´t execute it. The variable definitely works for the other code in constructor.php.
If I´m copy&paste the code of template.php into constructor.php after $content.= its working like a charm. But I want to restructure my constructor.php because its getting to big and this way its easier to customize.
I don´t know how to describe this problem more exactly, but I´m hoping this title fits to my problem.
Update your function
function requireToVar($file,$row_id){
ob_start();
require($file);
return ob_get_clean();
}
so you can call it like that
while ($row = $sqli->fetch_assoc()) {
$ii++;
if($row['dummy']=="Example"){
$content.=requireToVar('template.php',$row['id']);
and display it in template.php like that
<div class="image-wrapper" id="dt-<?php echo $row_id; ?>" style="display: none;"></div>
Use MVC model and renderer functions. For example: index.php
<!DOCTYPE HTML>
<html>
<head>
<title><?=$title; ?></title>
</head>
<body>
<h3><?=$text; ?></h3>
</body>
</html>
Than I'll have PHP array that contains those variables:
$array = array("title"=>"Mypage", "text"=>"Mytext");
Now we will use both in renderer function
function renderer($path, $array)
{
extract($array); // extract function turn keys into variables
include_once("$path.php");
}
renderer("index", $array);
Your approach is rather strange, but anyway; you can access $row from within $GLOBALS array.
Write your template as:
<?php echo "
<div class='image-wrapper' id='dt-".$GLOBALS['row']['id']."' style='display: none;'>
...
</div>
";
?>
probably a newb question here, but how do I return a CI anchor() call from within a function. I want to "hide" a button if a variable is set to a certain value.
CI's URL helper documentation: https://www.codeigniter.com/user_guide/general/helpers.html
A pseudo example that won't work (can't return the URL helper anchor('',''):
$prevAvailCompID = 0;
function hideButton($prevCompID)
{
if($prevCompID == 0)
{
return anchor('/getcomps/getSpecificComp/'.$prevCompID , 'PREV COMP');
//I've also tried return echo anchor(...)
}
}
further down on the page:
<div id="prevBtnContainer"><? hideButton($prevAvailCompID); ?></div>
You don't need to return the anchor() function. You can just use as this
UPDATED CODE
public function test(){
?>
<h1>test H1</h1>
<div id="prevBtnContainer"><?php $this->hideButton(0); ?></div>
<div id="1prevBtnContainer"><?php $this->hideButton(1); ?></div>
<?php
}
private function hideButton($prevCompID)
{
if($prevCompID == 0)
{
echo anchor('/getcomps/getSpecificComp/'.$prevCompID , 'PREV COMP');
}
}
I've tested this in my CodeIgniter and its working.
Where should we process mysql queries in CodeIgniter application?
For example in a simple project we do like this :
for controller:
class Blog extends CI_Controller {
function posts(){
$data['query'] = $this->blog_model->index_posts();
$this->load->view('blog_view', $data);
}
}
and in view :
<?php
while ($post = mysql_fetch_object($query)):
?>
<div>
<p><?= $post->body; ?></p>
</div>
<?php endwhile; ?>
But, if we want to do something with body of post before print where should it be done?
For example, I want to write a function that formats the body of post and pass the body to it before doing echo.
Where should it be placed according to CoeIgniter's structure and recommended practices? (best option)
in the controller? (if so , how to use it)
in the view?
write a helper?
other approaches ?
Here's what is recommended:
Controller:
function posts() {
$this->load->model("blog_model");
$data['rows'] = $this->blog_model->index_posts();
$this->load->view("blog_view", $data);
}
Model: (blog_model.php)
function index_posts() {
$this->load->database();
$query = $this->db->get('your_table');
$return = array();
foreach ($query->result_array() as $line) {
$line['body'] = ... do something with the body....
$return[] = $line;
}
return $return;
}
View: (blog_view.php)
<?php foreach ($rows as $line): ?>
<div>
<p><?php echo $line['column']; ?></p>
</div>
<?php endforeach; ?>
Basically what happens is your model returns a multidimensional array that is passed the view and processed using a foreach() loop.
Good luck!
If you want to reuse that function create a helper. If you want this function only once put it in your controller and call from that controller.
Models are just for accessing database or maybe in few other cases, but mostly just for accessing things in database or editing, deleting etc. and sending the result to controller for further processing.
In your case I would stick with helper.
E.g. you will create a file top_mega_best_functions.php and put it inside helpers folder.
Than you write ther e.g. something like
function red_text($input) {
echo '<span style="color: red;">';
echo $input;
echo '</span>';
}
Then load the helper in your autoloader file or load before using.
And use in your view or controller like
$blablabla = "This text will be red";
red_text($blablabla);
This is very simple to understand
Image Class
<?php
class Image extends Zend_Db_Table_Abstract {
protected $_name = 'images';
public function getList() {
return $this->fetchAll();
}
}?>
My PHP Code
<?php
require 'config.php';
$imgTable = new Image(); // Create Object
$imgList = $imgTable->getList(); // fetch Data
$template = new Template('portfolio'); // Initialize Template and tell which template to pick
$template->imgList = $imgList; // set template variable
$template->render(); // Generate Template output
?>
I can access template variable inside template using $this
Below code is from inside the template
$xback = 0;
foreach ($this->imgList as $images) {
echo 'imageArray[' . $xback . '] = "' . $images['sef'] . '";';
$xback++;
}
?>
.......
<?php
foreach ($this->imgList as $images) {
?>
<div class="portfolio_item">
<img src="<?php echo PATH_WEB . $images['image_thumb'] ?>" height="146" width="209" />
<div class="title"><?php echo $images['image_title'] ?></div>
<div class="right link">
View Details
</div>
</div>
<?php
}
?>
Above code is working fine, but below some few lines, I have to iterate over the same data again dont output any thing. If I comment the first one, 2nd starts working.
First one is to create the JS array and is in head section,
Second part is in HTML to display images
I hope its a pointer issue, I may have to set the loop current item to start, but I am not understanding it right now .... reset($this->imgList) didnt worked
please help
I think it has something to do with the fetchAll call, try this:
<?php
class Image extends Zend_Db_Table_Abstract {
protected $_name = 'images';
protected $images;
public function getList() {
// Employ lazy loading pattern to load images if they aren't set yet
if (!isset($this->$images)) {
$this->images = $this->fetchAll();
}
return $this->images;
}
}?>