I just go to the point.
Nvm need to add more text to much code..
Trying to load a Template with php inside it but php prints in html instead.
Init.php
class Init {
public static $ROOT = '';
public static $TEMPLATE = '';
public static $SERVICE = '';
public static function start() {
// Init Paths
Init::$ROOT = str_replace("\\", "/", __DIR__);
Init::$TEMPLATE = Init::$ROOT . "/Template/";
Init::$SERVICE = Init::$ROOT . "/Service/";
// Init Template.php class
require_once(Init::$SERVICE . "Template.php");
// Load template Top.php
$top = new Template(Init::$TEMPLATE . "Layout/Top.php");
echo $top->load(); // Show Top.php
}
}
Top.php
<!DOCTYPE html>
<html>
<?
// Load template Head.php
$head = new Template(Init::$TEMPLATE . "Layout/Head.php");
$head->set("TITLE", "Dashboard"); //Set [#TITLE] to Dashboard
$head->load(); // Show Head.php
?>
</html>
Head.php
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[#TITLE] | cwEye</title> <!-- [#TITLE] will be Dashboard-->
<?
echo "Hello"; // ERROR -> This will print <? echo"Hello"; ?> in my page
?>
</head>
Template.php
<?
class Template {
protected $file;
protected $values = array();
private static $templateFile = null;
public function __construct($file) {
$this->file = $file;
}
public function set($key, $value) {
$this->values[$key] = $value;
}
// This code works but it will not load php inside
public function load() {
if (!file_exists($this->file)) return "Error loading template file ($this->file).";
ob_start();
include_once($this->file);
$data = ob_get_clean();
foreach ($this->values as $key => $value) {
echo str_replace("[#$key]", $value, $data);
}
if(count($this->values) == 0) echo $data;
}
}
?>
Ive played with allot of functions to make it but it does not work...
It just prints the php in html.
Tried with
ob_start();
include_once(FILE);
$data = ob_get_clean();
Don't use short tags like <? or <?=, use <?php instead. You probably have your short_open_tag set to false in php.ini. If you are using PHP 7 then you should know short tags were removed completely and wont work anymore.
In head.php use the full tag. Change
to
<?php echo "hello"; ?>
Related
Im building a php project.
This is the structure
This is my init.php
<?php
use App\Core\Container;
require_once __DIR__."/../autoloader.php";
require_once __DIR__."/Core/Container.php";
$container = new Container();
which gets used within the index.php
<?php
require "./src/init.php";
$pathinfo = $_SERVER["PATH_INFO"];
$routes= [
"/team" => ['TeamController',
'showTeampage'],
];
if(isset($routes[$pathinfo])){
$controllername = $routes[$pathinfo][0];
$method = $routes[$pathinfo][1];
$controller = $container->make($controllername);
}
This is the container php where the problem occurs:
<?php
namespace App\Core;
use PDO;
use App\Team\TeamController;
use App\Team\TeamRepository;
class Container {
public $storage = [];
public $buildManuals = [];
public function __construct() {
$this->buildManuals = [
'pdo'=> function () {
$pdo = new PDO('mysql:host=localhost;dbname=vanillaPHP;charset=utf8', 'root', '');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
return $pdo;
},
'TeamController'=> function() {
$controller = new TeamController();
},
'TeamRepository'=>function() {
return new TeamRepository($this->make("pdo"));
},
];
}
public function make(String $string) {
if(empty($this->storage[$string]) ) {
$this->storage[$string] = $this->buildManuals[$string]();
}
return $this->storage[$string];
}
When Im entering the following URI he makes a TeamController onject I have tested it.
But he prints out the number 4 in UI for what ever reason. Why is this happening?
This is my TeamController class btw
namespace App\Team;
use App\Core\AbstractController;
use App\Team\TeamRepository;
class TeamController {
public $name ="test";
// public function __construct(Teamrepository $teamRepo)
// {
// $this->teamRepo = $teamRepo;
// }
public function hi() {
echo "hi";
}
// public function showTeampage() {
// $teammembers = $this->teamRepo->fetchAll();
// $this->render($this->teamRepo->getTableName(),
// [
// 'params'=>$teammembers
// ]);
// }
}
This is the viewfield for the team:
<?php require __DIR__."../../../Components/Head.php"; ?>
<p>Hi im the team view</p>
<!-- TODO: display the team data in a beautiful way -->
<?php foreach($params as $teammember): ?>
<p>
<!-- <?php echo $teammember->firstname ?> -->
</p>
<?php
endforeach;
?>
<?php require __DIR__."../../../Components/Footer.php"; ?>
And this is the Components/Head.php:
<?php
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>The company</title>
</head>
<body>
I am currently trying to create a small template engine for a project that I am working on, and I am using a system where I am replacing {$tag} with a preset tag. So say I put {username} in my template file, it will return a string which is the username. Now I want to go beyond just a simple string replacing a string. So using the same code I put
$tpl->replace('getID', '<?php echo "test"; ?>);
And it didn't work, so when I went to inspect element, I saw that it returned <!--? echo "test"; ?-->...
So now I am just trying to figure out why it returned commented code.
Here is my class file:
class template {
private $tags = [];
private $template;
public function getFile($file) {
if (file_exists($file)) {
$file = file_get_contents($file);
return $file;
} else {
return false;
}
}
public function __construct($templateFile) {
$this->template = $this->getFile($templateFile);
if (!$this->template) {
return "Error! Can't load the template file $templateFile";
}
}
public function set($tag, $value) {
$this->tags[$tag] = $value;
}
private function replaceTags() {
foreach ($this->tags as $tag => $value) {
$this->template = str_replace('{'.$tag.'}', $value, $this->template);
}
return true;
}
public function render() {
$this->replaceTags();
print($this->template);
}
}
And My index file is:
require_once 'system/class.template.php';
$tpl = new template('templates/default/main.php');
$tpl->set('username', 'Alexander');
$tpl->set('location', 'Toronto');
$tpl->set('day', 'Today');
$tpl->set('getID', '<?php echo "test"; ?>');
$tpl->render();
And my template file is:
<!DOCTYPE html>
<html>
<head></head>
<body>
{getID}
<div>
<span>User Name: {username}</span>
<span>Location: {location}</span>
<span>Day: {day}</span>
</div>
</body>
</html>
You're redeclaring PHP in a php file when there is no need to. i.e. you're trying to print <?php which is why it's messing up.
So, you can replace this:
$tpl->set('getID', '<?php echo "test"; ?>');
with this
$tpl->set('getID', 'test');
But, you obviously already know that, you're just trying to go further, the way to do this is by using php inside the set. So, as an idea, you could try this:
$tpl->set('getID', testfunction());
(You're calling testfunction here to define the 'getID' here btw)
So, now you want to write a little function to do something fancy, for the sake of this example:
function testfunction(){
$a = 'hello';
$b = 'world';
$c = $a . ' ' . $b;
return $c;
}
The above should then return hello world in place of {getID}
In reference to your comments - if you want to go one step further and start being more advanced with the return results, you can do the following:
function testfunction(){
$content = "";
foreach ($a as $b){
ob_start();
?>
<span><?php echo $b->something; ?></span>
Some link
<div>Some other html</div>
<?php
$content += ob_get_clean();
}
return $content
}
I'm loading the main view within the controller home as following:
class Home
{
public static function login()
{
Views::load('frontend/index', ['view' => 'account/login', 'name' => 'Stackoverflow']);
}
}
Now as you can see the view being loaded is frontend/index but I also say what is the view that must be loaded afterwards account/login.
So in the frontend/index.php file I have the following:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<?php Views::load($view); ?>
<?php echo $name; // prints 'stackoverflow' ?>
</body>
</html>
What happens is that I'm able to access the variable $name in the frontend/index file but not in the account/login file.
The account/login.php file contains:
<h2>Hello: <?php echo $name; // shows error saying 'Undefined variable: name' ?></h2>
The error just tells me that the variable is not being cached/stored.
Finally my view class has the following structure:
<?php
class Views
{
public static function load($file, $data = null)
{
if(file_exists(VIEWS_PATH . $file . '.php') == FALSE)
throw new Exception('View not found');
if($data != null)
extract($data, EXTR_SKIP);
ob_start();
require_once(VIEWS_PATH . $file . '.php');
$content = ob_get_contents();
ob_end_clean();
// prints the view
echo $content;
}
}
What can I do in order to allow the variables sent by controller to be cached/stored and called in multiple views?
Here is my code:
My root directory is: root
An index.php file located at the root/index.php
<?php
require_once('root/includes/initialize.php');
<?php template('header.php', 'TITLE');?>;
?>
<div id="main">
//SOME CONTENT
</div>
My initialize.php file gets all my core include files and puts them into one "require_once". Located in root/includes/initialize.php
<?php
//Define Path
defined('LIB_PATH') ? null : define('LIB_PATH', 'root/includes/');
//Core Functions
require_once(LIB_PATH.'functions.php');
//Core Objects
require_once(LIB_PATH.'_database.php');
require_once(LIB_PATH.'_session.php');
//Classes
require_once(LIB_PATH.'_user.php');
?>
updated**
My functions.php file includes a simple templating function that grabs a template file such as my header.php. It is located in root/includes/functions.php
<?php
//Templating
function template($path="", $pageTitle=NULL) {
if ($pageTitle != NULL) {
$_POST['page_title'] = $pageTitle;
}
include(root/public/templates/'.$path);
}
?>
My _session.php file takes care of my session control. Located in root/includes/_session.php
<?php
/**
* Class for Sessions
*/
class Session
{
public $logged_in = FALSE;
public $uid;
function __construct() {
session_start();
$this->check_login();
}
public function check_login() {
if (isset($_SESSION['uid'])) {
$this->uid = $_SESSION['uid'];
$this->logged_in = TRUE;
} else {
unset($this->uid);
$this->logged_in = FALSE;
}
}
public function logged_in() {
return $this->logged_in;
}
public function login($user) {
if ($user) {
$this->uid = $_SESSION['uid'] = $user;
$this->logged_in = TRUE;
}
}
public function logout() {
unset($_SESSION['uid']);
session_unset();
session_destroy();
redirect(WEB_ROOT);
}
}
$session = new Session();
?>
updated**
My header.php holds the top of all the pages in my site. Located in root/public/templates/header.php. This is the file I'm having trouble with, I cant figure out why I am unable to echo out the $session->uid or the $_SESSION['uid'] in this file.
<html>
<head>
<!--CSS-->
<link rel="stylesheet" type="text/css" href="root/public/css/style.css">
<title>MY SITE</title>
</head>
<body>
<div id="header">
<div id="logo">
<?php echo $_POST['page_title'];?>
</div>
<?php echo $session->uid;?> //DOESN'T WORK
</div>
I am able to echo out everything just fine in my index.php file and the other files on my site, but not in the included header.php. Any one know why? Thanks.
session_start() must be called at the start of EVERY php file that is going to either set or get a session variable. The only place I see you calling session_start() is in the one file.
http://www.php.net/manual/en/session.examples.basic.php
<?php
session_start();
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
} else {
$_SESSION['count']++;
}
?>
Also on a side note. I'm looking at your class Session and I'm not seeing any $mySession = new Session(); anywhere to also start a session.
UPDATE:
I recreated your basic file structure and code in my IDE and got it work by adding this line in the class.
public function check_login() {
if (isset($_SESSION['uid'])) {
$this->uid = $_SESSION['uid'];
$this->logged_in = TRUE;
}
else {
unset($this->uid);
$this->logged_in = FALSE;
$_SESSION['uid'] = session_id();
/*Add this next line */
$this->uid = $_SESSION['uid'];
}
}
The first time I ran index.php just the <?php echo $_SESSION['uid']; ?> part of header worked. Refreshed and <?php echo $session->uid; ?> also worked so it echoed twice. This tells me your class isn't assigning the ID to a class variable, hopefully this is the desired out come as it worked on my end, or you can tweek it as needed.
UPDATE 2:
Function File (edit to match your paths but you need to return a string)
<?php
//Templating
function template($path = "", $pageTitle = NULL) {
if ($pageTitle != NULL) {
$_POST['page_title'] = $pageTitle;
}
return "$path";
}
?>
Then in the Index.php file add this way instead:
<?php
require_once('initialize.php');
include(template('header.php', 'TITLE'));
//include('header.php');
?>
<div id="main">
//SOME CONTENT
</div>
</body>
</html>
_session.php file:
<?php
/**
* Class for Sessions
*/
class Session
{
public $logged_in = FALSE;
public $uid;
function __construct() {
session_start();
$this->check_login();
}
public function check_login() {
if (isset($_SESSION['uid'])) {
$this->uid = $_SESSION['uid'];
$this->logged_in = TRUE;
}
else {
unset($this->uid);
$this->logged_in = FALSE;
$_SESSION['uid'] = session_id();
$this->uid = $_SESSION['uid'];
}
}
public function logged_in() {
return $this->logged_in;
}
public function login($user) {
if ($user) {
$this->uid = $_SESSION['uid'] = $user;
$this->logged_in = TRUE;
}
}
public function logout() {
unset($_SESSION['uid']);
session_unset();
session_destroy();
redirect(WEB_ROOT);
}
}
$session = new Session();
?>
And header.php
<html>
<head>
<!--CSS-->
<link rel="stylesheet" type="text/css" href="style.css">
<title>MY SITE</title>
</head>
<body>
<div id="header">
<div id="logo">
<?php echo $_POST['page_title'];?>
</div>
<?php echo $session->uid; ?> //WORKS NOW
<?php echo $_SESSION['uid']; ?> //WORKS NOW
</div>
The question is pretty vague. My guess would be, that since your index.php file in located in root/index.php, then your include paths:
require_once('root/includes/initialize.php');
include('root/public/templates/header.php');
are incorrect. You don't start with a /, so paths are relative, and considering the location of your index.php, you are including root/root/includes/initialize.php. If that's the case, you should easily spot that by the lack of <title>MY SITE</title> and TITLE on your page. Haven't you?
If that's the problem, I suggest you define some kind of HOME constant, for example
define ('HOME', dirname(__FILE__));
// or define ('HOME', __DIR__); depending on your PHP version
so that you can then include everything relative to that constant
require_once(HOME . '/includes/initialize.php');
Other than that I don't see any errors in your code.
So, I have a template engine I made and I want to replace {pageBody} with contents from a PHP file, when I do it using the template engine it does not execute the PHP, rather it displays it in view source option.
TEMPLATE.PHP
<?php
class TemplateLibrary {
public $output;
public $file;
public $values = array();
public function __construct($file) {
$this->file = $file;
$this->file .= '.tpl';
$this->output = file_get_contents('templates/'.$this->file);
}
public function replace($key, $value)
{
$this->values[$key] = $value;
}
public function output() {
foreach($this->values as $key => $value)
{
$ttr = "{$key}";
$this->output = str_replace($ttr, $value, $this->output);
}
return $this->output;
}
}
index.tpl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>{page_title}</title>
{page_style}
</head>
<body>
{page_header}
{page_body}
{page_footer}
</body>
</html>
HTML replace works fine, but PHP does not. Any ideas?
You are rather scattered with your files and the list is incomplete. I've listed all the files you've provided so far below.
#Jonathon above is correct, that you will need to use output buffering to capture the output of the PHP file and include() the file (so it gets executed) instead of using file_get_contents() (which does not execute the file).
[edit] I re-created all these files in my local environment and confirmed that #Jonathon's suggestion worked perfectly. I've updated dev/replacements.php to include the suggested code.
Additionally, I added two more functions to your TemplateLibrary class : replaceFile($key, $filename) that does the file_get_contents($filename) so that you don't have to repeat it so often, and replacePhp($key, $filename) that performs an include() while capturing the output, so you can encapsulate the complexities of including a PHP file.
Good Luck!
main.php
<?php
require_once 'dev/dev.class.php';
require_once 'dev/templatelibrary.php';
$dev = new dev('netnoobz-billing');
$dev->loadLib('JS', 'js', 'jquery');
// template library and required files
$template = new TemplateLibrary('index');
require_once 'dev/replacements.php';
echo $template->output();
dev/templatelibrary.php
<?php
class TemplateLibrary {
public $output;
public $file;
public $values = array();
public function __construct($file) {
$this->file = $file;
$this->file .= '.tpl';
$this->output = file_get_contents('templates/'.$this->file);
}
public function replace($key, $value)
{
$this->values[$key] = $value;
}
public function replaceFile($key, $filename)
{
$this->values[$key] = file_get_contents($filename);
}
public function replacePhp($key, $filename)
{
ob_start();
include($filename);
$data = ob_get_clean();
$this->values[$key] = $data;
}
public function output() {
foreach($this->values as $key => $value)
{
$ttr = "{$key}";
$this->output = str_replace($ttr, $value, $this->output);
}
return $this->output;
}
}
index.tpl
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>{page_title}</title>
{page_style}
</head>
<body>
{page_header}
{page_body}
{page_footer}
</body>
</html>
replacements.php
<?php
$configStyleSheet = '<style type="text/css">'
. file_get_contents('styles/default/main.css')
. '</style>';
$pageHeader = file_get_contents('templates/header.tpl');
$pageFooter = file_get_contents('templates/footer.tpl');
#$pageBody = file_get_contents('loaders/pageBody.php');
ob_start();
include('loaders/pageBody.php');
$pageBody = ob_get_clean();
$template->replace('{page_style}' , $configStyleSheet);
$template->replace('{page_title}' , 'NetBilling');
$template->replace('{page_header}', $pageHeader);
$template->replace('{page_footer}', $pageFooter);
$template->replace('{page_body}' , $pageBody);
loaders/pageBody.php
<?php echo 'test'; ?>
[edit] added loaders/pageBody.php from OP's comment.
[edit] Updated dev/replacements.php to capture output buffer and use include on .php
You're using file_get_contents in your pastebin code but you should be using your template processor or PHP's include() instead. If you do $template->replace('{page_header}', $pageHeader), $pageHeader is just the source of the tpl and your template processor does not know that so it will just replace the tag with that source. Fix:
$pageHeader = new TemplateLibrary('header');
// ...
$template->replace('{page_header}', $pageHeader->output());
For the PHP files, you should call include() on the file, wrapped in output buffering, so you can pass the output of the PHP execution as the template variable, instead of the PHP source itself:
ob_start();
include('loaders/pageBody.php');
$pageBody = ob_get_clean();
/// ...
$template->replace('{page_body}', $pageBody);