As of right now I've created a template class, and I've created a registration class. But I'm having trouble getting the two to work properly together so that I can display my variables in my template files.
Here are the basics of my template class:
class siteTemplate {
function getTemplate($file, $varesc=false) {
if (file_exists("templates/" . $file)) {
$data = file_get_contents("templates/" . $file);
$data = str_replace("\"","\\\"", $data);
$data = str_replace("\'","\\\'", $data);
$data = str_replace("\\n","\\\n", $data);
if($varesc)
$data = str_replace("\$","$", $data);
return $data;
} else {
die("Error.<br />Could not find <strong>" . $file . "</strong>.");
}
}
function createGlobal() {
global $siteName, $siteUrl;
global $content;
eval("\$main = \"".$this->getTemplate("main.html")."\";");
echo $main;
}
}
$tp = new siteTemplate();
A function from my registration class:
public function get_username($uid) {
$result = mysql_query("SELECT username FROM users WHERE uid = $uid");
$user_data = mysql_fetch_array($result);
echo $user_data['username'];
}
I can echo out data from my registration class in index.php
echo $user->get_username($uid);
BUT I can't do the same thing within my template files. What adjustments do I need to make to make this work together. Live example: http://www.aarongoff.com/i
Username: test
Password: test
If you look I'm echoing out "Logged in as: test"
But when I try to call for that variable within my template file it just displays "Logged in as:"
(I know there are SQL vulnerabilities, I'm just testing to get my classes to work)
The true answer to this is that PHP IS a template! Use pure PHP code as your templates. Then you don't have to keep reimplementing every one of PHP's features in your ad hock template class.
This is called the http://en.wikipedia.org/wiki/Inner-platform_effect and you should avoid it. Just use PHP directly, it's what it was made for.
What you should do is be disciplined about naming the PHP files, and separating concepts logically. But don't try to reimplement PHP in PHP.
Related
I have tried the solutions indicated here on stackoverflow, the code below uses one of them, recommended and voted as the right way to do it, but it doesn't work for me, why?
In fact the href results empty.
<?php
//URLS LIST
$nameA = 'http://www.example.com';
$nameB = 'http://www.example.com';
$nameC = 'http://www.example.com';
class bannClass {
private $class_varA;
private $class_varB;
private $class_varC;
public $username = '';
public function __construct($nameA, $nameB, $nameC) {
$this->class_varA = $nameA;
$this->class_varB = $nameB;
$this->class_varC = $nameC;
}
public function check_userOne() {
$url = 'https://example.com/wp-content/uploads/sponsor/' . $this->username . '/sponsor1.jpg';
return '<img src="' . $url . '" alt="Sponsor"/>';
}
public function check_userTwo() {
$url = 'https://example.com/wp-content/uploads/sponsor/' . $this->username . '/sponsor2.jpg';
return '<img src="' . $url . '" alt="Sponsor"/>';
}
public function check_userThree() {
$url = 'https://example.com/wp-content/uploads/sponsor/' . $this->username . '/sponsor3.jpg';
return '<img src="' . $url . '" alt="Sponsor"/>';
}
}
Also how can i make those 3 variables at the top dynamic in php? instead of "name" something like $($this->username . 'A') , $($this->username . 'B') , etc.
EDIT: the above class is being instantiated in another php file like so:
<?php
require_once('myclass.php');
$bannClass = new bannClass();
$bannClass->username = $data['username'];
//etc.
and used like:
<?php echo $bannClass->check_userOne();?>
As it is written, you must inject 3 values when it is instantiated. If you have error reporting turned on in your development environment (and you really should), it would have complained when you instantiated it as $bannClass = new bannClass();
This is how this object should be instantiated:
$nameA = 'http://www.example.com';
$nameB = 'http://www.example.com';
$nameC = 'http://www.example.com';
$bannClass = new bannClass($nameA, $nameB, $nameC);
I would make a few suggestions:
Don’t mix logic and presentation. A good rule of thumb to follow is no html outside of the view. Objects are generally for logic, not formatting html. Leave html for helper functions and the “view” portion of the script (which should be the very last thing that happens)
Keep it DRY (don’t repeat yourself). If you have methods doing the same thing, it’s time to refactor. Pass in a variable or an array for the method to work with.
—-
Further ideas relating to your comment:
The collection of the urls would typically be the job of an object. (Look into the PDO object. Helpful reference )
In all my projects, I use an object (named Database) to wrap around php’s db access, similar to pdo. It includes the following 3 methods (code is omitted for brevity):
public function prepare(string $query) { ... }
public function execute(array $params) { ... }
public function nextRecord() {...}
In a procedural script, you would first do whatever initialization is needed, deal with any user input using the PRG pattern, and any other logic. Then you would output the html, using php only to loop and insert variables. In OOP terms, this roughly corresponds to the MVC pattern (which is well worth learning).
So, for the example, let’s say that we have a database of urls:
ID URL Image
1 foo.com Image1.com
2 bar.com Image2.com
3 baz.com Image3.com
A procedural script could go as follows:
<?php
require(‘database.php’);
// optionally deal with user input
$url = new Database; // example is assuming connection is handled in the object
$url->prepare(“select url, image from sometable”);
$url->execute();
// all logic is complete; now give the output
?>
<!— html stuff —>
<ul>
<?php while($row=$url->nextRecord() ): ?>
<li><img src="<?= $row->image ?>" alt="Sponsor"/></li>
<?php endwhile; ?>
</ul>
Admittedly, I haven’t explained my object; space does not permit. But this should give you an overview of what’s possible and how to display 150 urls without repeating yourself.
Just to add to excellent answer by Tim Morton: Let's suppose, that the three links are almost always the same, then you can do something like this:
class bannClass {
private $class_varA = 'https://example.com';
private $class_varB = 'https://example.com';
private $class_varC = 'https://example.com';
public $username = '';
public function __construct($nameA = null, $nameB = null, $nameC = null) {
if (!empty($nameA)) $this->class_varA = $nameA;
if (!empty($nameB)) $this->class_varB = $nameB;
if (!empty($nameC)) $this->class_varC = $nameC;
}
public function getVarA(){
return $this->class_varA;
}
public function getVarB(){
return $this->class_varB;
}
public function getVarC(){
return $this->class_varC;
}
}
What above does, that if the class is not called with any parameters = $foo = new bannClass(); it will default all three URLs to what was set as default. Obviously, you should arrange the variables in such manner, that first is possibly changed the most time:
$bar = new bannClass('https://stackoverflow.com');
echo $bar->getVarA(); // returns stackoverflow.com
echo $bar->getVarC(); // returns example.com
Because changing only third parameter looks kinda stupid:
$baz = new bannClass(null,null,'https://stackoverflow.com');
cho $baz->getVarA(); // returns example.com
echo $baz->getVarC(); // returns stackoverflow.com
I was wandering if it were possible to store a html schema page with special strings to replace with variable and how to do it.
In an external file, I would like to put the html structure of a product, let's call it schema.php:
<span id="{% id %}">{%= name %}</span>
<span>{%= imageURL() %}</span>
The example above is just a simpler example. In the external file, the html would be more complex. I know that if there were just few lines I could just echo them with a simple function but this is not the case.
In another file I have a class that handle products, let's call it class.php:
class Product {
//logic that is useless to post here.
public function imageURL() {
return "/some/url".$this->id."jpg";
}
}
In this class I would like to add a function that take the content from schema.php and then echo it in the public file for users.
I tried with file_get_contents() and file_put_contents() but it just doesn't work:
$path_to_file = 'data/prodotti/scheda.inc';
$file_contents = file_get_contents($path_to_file);
$file_contents = str_replace(
"{%= ",
"<?php echo $this->",
$file_contents
);
$file_contents = str_replace(
" }",
"; ?>",
$file_contents
);
file_put_contents($path_to_file, $file_contents);
is it possible to call schema.php page and print it with custom variables?
By "schema page" I think you mean "template" and yes, but the best way to do it is to use an existing templating engine such as Smarty or a Mustache implementation like https://github.com/bobthecow/mustache.php instead of implementing it yourself because of the risks of XSS, HTML-injection, and how you'll eventually want features like looping and conditionals.
you can do it normaly with php require func. without any strings to replace, if you just want to use that file as "template" then:
in schema.php:
<?php
echo'<span id="'.$id.'">'.$name.'</span>
<span>'.$imageURL.'</span>';
?>
in class.php:
<?php
class Product {
//logic that is useless to post here.
public function imageURL() {
return "/some/url".$this->id."jpg";
}
}
$imageURL = imageURL(); ?>
Index.php or whatever the main page that handles class.php and temp.php(schema)
<?php
//avoid undefined variables on errors
//in case that you don't check for values submitted
$id = 0;
$name = 0;
$imageURL = '';
//set vars values
$id = /*something*/;
$name = /*something 2*/;
$imageURL = /*something3*/;
//all date will be replaced is ready, oky nothing to wait for
require('path/to/schema.php');
Note: If you gets these data from user, then you should validate with if(isset()).
hope that helps,
I am creating website in PHP. I am using MVC in PHP. My website works like this, if user go to example.com/about then it it will load About class and index() function. If user will go to localhost/about/founder then it will load founder() function from About class. but the thing is that if I go to localhost/About or localhost/AbOut or anything like that it is loading default index() function from About class file. So what to do with case sensitivity? I mean I want my script to load index() function from class file if it is localhost/about or localhost/terms. If anything is in uppercase, then it should load 404 error function. 404 error function is already set in my site.
Please help me friends.
here is my Bootstrap.php class file
<?php
/*
Bootstrap class to run functions by URL
*/
class Bootstrap {
public $_req;
public $_body;
public $_file;
public $_error;
function __construct(){
if(empty($_GET['req'])){
require 'classes/home.php';
$this->_body = new Home();
$this->hdr($this->_body->head());
$this->_body->index();
$this->ftr();
exit();
}
$this->_req = rtrim($_GET['req'], '/');
$this->_req = explode('/', $this->_req );
$_file = 'classes/'.$this->_req[0].'.php';
if(file_exists($_file)){
require $_file;
}
else {
$this->error(404);
}
$this->_body = new $this->_req[0];
$this->hdr($this->_body->head());
if(isset($this->_req[2])){
if(method_exists($this->_req[0], $this->_req[1])){
$this->_body->{$this->_req[1]}($this->_req[2]);
}else {
$this->error(404);
}
}else {
if(isset($this->_req[1])){
if(method_exists($this->_req[0], $this->_req[1])){
$this->_body->{$this->_req[1]}();
}else {
$this->error(404);
}
}else {
$this->_body->index();
}
$this->ftr();
}
}
//this function is to set header in html code
public function hdr($var = false){
echo '<!DOCTYPE HTML><html><head>'.$var.'</head><body>';
}
//this function is tp set footer in html code
public function ftr($var = false){
echo $var.'</body></html>';
}
//error handler
public function error($var){
require 'classes/er_pg.php';
$this->_error = new Error();
$this->_error->index($var);
}
}
You shouldn't use anything to load non-lowercase URLs because of the duplicate content, and that's a good thing you're doing. The wrong URLs should fail automatically in such cases.
However, since you didn't show how are you making those calls, then only thing I can suggest at this point is to check if the called method exists (case-sensitive), and if not, throw/redirect to a 404 page (header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");).
UPDATE
After all the chat in the comments, seems like file_exists is not case-sensitive in your case, which is really weird. Hopefully someone will be able to figure it out so I can delete this (keeping it because of the info in the comments).
I solved the problem. I used this
if(ctype_lower($this->_req[0])){
$_file = 'classes/'.$this->_req[0].'.php';
and now its working. Thanx anyways friends.
I have component called mycomponent
models
paypal.php
controllers
paypal.php
views
paypal
view.html.php
index.html
tmpl(folder)
default.php
index.html
In controller i have this code
<?php
// No direct access.
defined('_JEXEC') or die;
jimport('joomla.application.component.controlleradmin');
/**
* Objectdefects list controller class.
*/
class MycomponentControllerPaypal extends JControllerAdmin
{
public function paypaldetails()
{
$model = $this->getModel('paypal');
// Get token
$token = urlencode(htmlspecialchars(JRequest::getVar('token')));
if (!$token)
{
// Missing $token parameter
$app = JFactory::getApplication();
$app->enqueueMessage(JText::_('COM_INSTALLER_MSG_MISSING_TOKEN'));
}
else
{
// Install plugin
$model->paypaldetails($token);
}
}
}
In model i have this fragment of code
public function paypaldetails($token){
$environment= $this->environment;
// Add request-specific fields to the request string.
$nvpStr = "&TOKEN=$token";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = $this->PPHttpPost('GetExpressCheckoutDetails', $nvpStr);
//var_dump($httpParsedResponseAr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
$paypaldetails=array();
$paypaldetails["firstname"]= $httpParsedResponseAr['FIRSTNAME'];
$paypaldetails["lastname"] = $httpParsedResponseAr["LASTNAME"];
$paypaldetails["countrycode"] = $httpParsedResponseAr["COUNTRYCODE"];
$this->paypaldetails=$paypaldetails;
$a=$this->paypaldetails;
var_dump($a);
} else {
exit('GetExpressCheckoutDetails failed: ' . print_r($httpParsedResponseAr, true));
}
}
In view/template/default.php i have this
<?php
// no direct access
defined('_JEXEC') or die;
// Import CSS
$document = JFactory::getDocument();
$document->addStyleSheet('components/com_mycomponent/assets/css/defects.css');
$results = $this->items;
var_dump($results);
echo 'Firstname: '.$results[firstname];
echo '<br>Lastname: '.$results[lastname];
echo '<br>Countrycode: '.$results[countrycode];
When i run this url index.php?option=com_fewostar&view=paypal&task=paypal.paypaldetails&token=EC-92L7275685367793U&PayerID=TGWAUKNJLH2WL
I view first var_dump($a); located on model, but second var_dump($results); located in views/paypal/tmpl/default.php not display, and field in view not display. for any reason this url not call view. When i run this url index.php?option=com_fewostar&view=paypal code without task, view is display. but for this url
index.php?option=com_fewostar&view=paypal&task=paypal.paypaldetails&token=EC-92L7275685367793U&PayerID=TGWAUKNJLH2WL no display view. How i call view for this task, may be i need other view file, different of default.php?
I see a couple of problems here.
First, the code is not exactly using Joomla MVC style (even if it works for you, might be harder for people familiar with Joomla to debug).
Model method should be called getPaypaldetails and return something
public function getPaypaldetails()
{
// For Joomla 1.7+ use JInput instead of JRequest (deprecated)
$token = JFactory::getApplication()->input->getVar('token');
// some code
return $paypaldetails;
}
view.html.php should and get and data from model and assign to itself
public function display($tpl = null)
{
// Get some data from the models
$items = $this->model->get('paypaldetails');
// If data are incorrect, show nice error message
// ...
$this->items = $items;
}
View Layout file should be placed in /com_fewostar/views/paypal/tmpl/default.php
By default, the view is only called by the "display" task (which is the default task). Since you use your own task, you need to either redirect to the view after your task is finished or try to load the display function at the end.
I'm building my own MVC framework and have encountered a problem when sending variables into views. The loadView() looks like this:
function loadView($view, $variables = array())
{
$file_path = APPLICATION_PATH . 'views/' . $view;
if (file_exists($file_path))
{
if (is_readable($file_path))
{
if (! empty($variables)) extract($variables);
include($file_path);
}
else
{
throw new Exception('Could not read view from ' . $file_path);
}
}
else
{
throw new Exception('Could not load view from ' . $file_path);
}
}
It works just as expected. However, when I'm setting up a template view like this things get weird:
loadView('layout/header.php');
loadView($view);
loadView('layout/footer.php');
It's called like this ($user is an object):
$data['view'] = 'login/showUser.php';
$data['user'] = $user;
loadView('layout/template.php', $data);
The $view variable gets set in the template file and loads the correct view. However, the $user variable is unable to travel into the dynamically loaded view which only contains this code:
<p>User ID: <?php echo $user->id; ?></p>
I can do this in CodeIgniter and I find it a little weird since when the $view and $user variables are extracted in the first loadView() call to the template, they should be available to the next view which is simply included into the scope.
What did I overlook?
Each loadView() call has its own local scope, which are not shared between different invocations of loadView(). In CodeIgniter, this likely works because its view renderer stores the variables in some static storage. You need to pass all variables you need in each view explicitly, or you need to add static storage to loadView(), like this:
function loadView($view, $variables = array())
{
static $static_vars = array();
$static_vars = array_merge($static_vars, $variables);
...
extract($static_vars); // instead of extract($variables);
...