I'm trying to edit a template system so where I can use params such as [title] and it'll show my title in the included page. But I also want to be able to use php code inside of it and be able to execute that code. But I am having difficult getting them both to work at the same time.
I have tried to use include instead of file_get_Contents but when I use include, the params no longer work. However when I use file_get_contents the php doesnt work, and doesnt show.
My code:
class Template {
public function __construct($directory){
$this->dir = $directory;
}
public function setPage($pageName){
$this->directory = 'lib/' . $this->dir . '/' . $pageName . '.php';
if(file_exists($this->directory)) {
$Content = file_get_contents($this->directory);
}
}
public function newParam($trans, $val){
$this->param['[*' . $trans . '*]'] = $val;
}
public function setParams($element){
$element = str_replace(array_keys($this->param), array_values($this->param), $element);
return $element;
}
public function Create(){
die($this->setParams($Content));
}
}
Hope someone can help. Thanks
Related
I'm currently having a problem displaying a page that's in a subfolder. The entire view of the site works fine, but for all the pages that are in a certain directory in the view folder, they are not displayed, that is, only the home page is displayed.
Controller:
class Controller {
protected function view($view, $data = []) {
if (file_exists('../app/views/' . $view . '.php')) {
include '../app/views/' . $view . '.php';
} else {
include '../app/views/404.php';
}
}
protected function loadModel($model) {
if (file_exists('../app/models/' . $model . ".php")) {
include '../app/models/' . $model . ".php";
return $model = new $model();
}
return false;
}
}
I'm almost sure that this is the problem because this code defines the display of only the files that are in the view directory, which does not include the files that will be found, for example, in the subdirectory. Can someone help me how to fix this problem? Thanks
I know this answer has been answered already but it seems like I couldn't understand anything in my case (I'm still very new to web developing, learning frontend since this october and I jumped onto php at the start of this month).
My function is supposed to check if user is logged in and I couldn't understand the answers I read for my problem cause it seems like in the answers I found, the functions weren't custom? I might be wrong and I hope if I am, you can laugh about it.
So, to get a bit of context, I encounter this error when I try to call the function "check_logged_in()" in one of my controllers, this controller in question (it's called Upload) extends the main Controller from my core folder (and I triple checked if my init file has required it so I can use it globally).
Then I call a custom function from the main controller to load models if needed (in this case, I need to load my user model to get access to the "check_logged_in()" function since it's written there).
And this is where thing happen. I'll provide a bit of code so you guys can understand what I'm saying.
The Upload controller
<?php
class Upload extends Controller
{
function index()
{
header("location:" . ROOT . "upload/image");
die;
}
function image()
{
$user = $this->loadModel("user");
if(!$result = $user->check_logged_in()){
header("location:" . ROOT . "login");
die;
}
$data['page_title'] = "Upload";
$this->view("upload", $data);
}
}
The main Controller
<?php
class Controller
{
protected function view($view, $data = [])
{
if (file_exists("../app/views/" . $view . ".php")) {
include "../app/views/" . $view . ".php";
} else {
include "../app/views/404.php";
}
}
protected function loadModel($model)
{
if (file_exists("../app/model/" . $model . ".php")) {
include "../app/model/" . $model . ".php";
return $model = new $model();
}
return false;
}
}
And the bit of code from the user model that is called
<?php
class User
{
function check_logged_in()
{
$DB = new Database();
if (isset($_SESSION['user_url'])) {
$arr['user_url'] = $_SESSION['user_url'];
$query = "select * from users where url_address = :user_url limit 1";
$data = $DB->read($query, $arr);
if (is_array($data)) {
//logged in
$_SESSION['user_name'] = $data[0]->username;
$_SESSION['user_url'] = $data[0]->url_address;
return true;
}
}
return false;
}
}
Thanks in advance for your time mates, I hope my noob self is clear enough for you to understand ^^'
Checking for the correct value of the $user variable should fix the error.
...
function image()
{
$user = $this->loadModel("user");
if(!$user || !$user->check_logged_in()){ // Here
header("location:" . ROOT . "login");
die;
}
$data['page_title'] = "Upload";
...
Then on $user is false condition will be
!false || !false->check_logged_in() which will lead to true.
Otherwise on $user is User:
!(object User) || !(object User)->check_logged_in() will call User::check_logged_in() method.
i saw a lot of ways that you can use to call a class inside another one in PHP and i want your opinion about the shortest version of calling a class.
lets say we have a class name view,
and another class name controller
class View
{
private $data = array();
private $render = FALSE;
public function __construct($template , $datas = null)
{
try {
$file = strtolower($template) . '.php';
if (file_exists($file)) {
if($datas > 0) {
foreach($datas as $data) {
array_push($this->data, $data);
}
}
$this->render = $file;
} else {
die('Template ' . $template . ' not found!');
}
}
catch (customException $e) {
echo $e->errorMessage();
}
}
public function __destruct()
{
extract($this->data);
include($this->render);
}
}
and
require_once "system/autoload.php";
class Controller {
function index() {
$view = new View('something');
}
i know that i can use
$view = new View('something');
or use OOP and extent and call a function from view inside controller like
$this->viewFunction();
but is there any way that i can call view class inside controller like this
View('something)
i want to make it shortest version possible
if it is not possible or i have to make change inside compiler well just give me the shortest version
thank you all
You can surely do this in PHP. Have a look at magic methods, especially __invoke()
class View
{
public function __invoke(string $template)
{
return $template;
}
}
You can simply invoke it by doing
$view = new View();
$view('my template');
I currently have this code in PHP:
public function newFile($folder, $file){
fopen($folder."/".$file, 'w');
}
That I use like this:
newFile('myfolder', 'myfile.txt');
It works fine, but I want to know if it's possible to create a function that I can use like this:
newFile('myfile.txt') inFolder('myfolder');
How can I do this, if it's possible?
I could also use this:
newFile('myfile.txt')->inFolder('myfolder');
I can see that you are trying to achieve a syntax like Objective-C and similar languages, but unfortunately, you can't. Just get used to the PHP syntax.
You could use an array to get named parameters, though:
function newFile($params){
fopen($params['folder']."/".$params['file'], 'w');
}
newFile(array(
'folder' => 'myfolder',
'file' => 'myfile.txt'
));
Alternatively you could use proxies to get to a syntax like: newFile(...)->inFolder(...), but that would definitely be an overkill here.
Here is an example of what you could possibly implement. Such technique is often used, when you need to call a lof of functions of the same object (better readability).
The point is that your functions may return the reference to the same object:
class Creator {
private $file ;
private $folder = "" ;
public function newFile($file){
$this->file = $file ;
return $this ;
}
public function inFolder($folder){
$this->folder = $folder ;
return $this ;
}
public function create(){
return fopen($this->folder."/".$this->file, 'w');
}
}
$creator = new Creator();
$creator
->newFile("test.txt")
->inFolder("test")
->create();
As for the solution of newFile('file')->inFolder('folder') it is possible, but it'd be definite overkill in this situation. Here's an example how to do it, though:
<?php
class File_To_Be_Created {
private $file;
public function __construct($file) {
$this->file = $file;
}
public function inFolder($folder) {
$handle = fopen($folder . '/' . $this->file, 'w');
if ($handle !== false) {
fclose($handle);
}
}
}
function newFile($file) {
return new File_To_Be_Created($file);
}
newFile('myfile.txt')->inFolder('myfolder');
?>
I have the following situation.
I have a class with a lot of functions. Each function starts with executing the same method. Is there a way that I can like implement this method into the function so that it is executed automatically?
Here is an example:
class test
{
static function_1($param) {some_method($param); other stuff....}
static function_2($param) {some_method($param); other stuff then function 1....}
static function_3($param) {some_method($param); other stuff then function 1 and function 2....}
}
So is there a way to execute some_method(); automaticly without declaring it in each function?
Thanks in advance!
Whole code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* The Assets Library
*
* This class let's you add assets (javascripts, stylesheets and images) way easier..
*/
class Assets {
private $css_url;
private $js_url;
private $img_url;
public function __construct()
{
$CI =& get_instance();
$CI->config->load('assets');
$asset_url = base_url() . $CI->config->item('assets_dir');
$this->css_url = $asset_url . $CI->config->item('css_dir_name');
$this->js_url = $asset_url . $CI->config->item('js_dir_name');
$this->img_url = $asset_url . $CI->config->item('img_dir_name');
}
// Returns the css html link
public function css_html_link($filename)
{
// Check whether or not a filetype was given
$filename = $this->_add_filetype($filename, 'css');
$link = '<link type="text/css" rel="stylesheet" href="' . $this->css_url . $filename . '" />';
return $link;
}
// Returns the css link
public function css_link($filename)
{
$filename = $this->_add_filetype($filename, 'css');
return $this->css_url . $filename;
}
// Returns the js html link
public function js_html_link($filename)
{
$filename = $this->_add_filetype($filename, 'js');
$script = '<script type="text/javascript" src="' . $this->js_url . $filename . '"></script>';
return $script;
}
// Return the js link
public function js_link($filename)
{
$filename = $this->_add_filetype($filename, 'js');
return $this->js_url . $filename;
}
// Returns the image html tag
public function img_html_link($filename, $rel = NULL)
{
// Get the filename without the filetype
$alt_text = substr($filename, 0, strpos($filename, '.')+1);
$alt_text = 'alt="'.$alt_text.'"';
// If relation is giving, use it
$img_rel = ($rel !== FALSE) ? 'rel="' . $rel . '"' : '';
$image = '<img src="' . $this->img_url . $filename . '" '.$rel.' ' . $alt_text . '/>';
return $image;
}
// Return the image link
public function img_link($filename)
{
return $this->img_url . $filename;
}
// Check whether or not a filetype was specified in $file, if not, it will be added
private function _add_filetype($file, $type)
{
if(strpos($file, '.' . $type) === FALSE)
{
$file = $file . '.' . $type;
}
return $file;
}
}
/* End of file assets.php */
/* Location: ./application/libraries/assets.php */
every time you initiate the class, it calls the __construct() function, or in PHP 4 (I hope you are not using php 4) it uses the function with the same name as the class
If you do this, it should work for every initiate of the class:
function __construct($param){
some_method($param);
}
if you call multiple functions in the same initiation of the class, you could do this:
var $param;
function __construct($param){
$this->param = $param;
}
function doMethod(){
some_method($this->param);
}
function function_1()
{
$this->doMethod();
}
Calling the class multiple times, with different params. Perhaps try this approach:
function __call($function, $param){
some_method($param);
switch ($function){
case 'function1':
$this->function1($param);
break;
/// etc..
}
}
I'm afraid that in this case the answer is 'no'.
You're not 'declaring' some_method() each time, you are calling it. If you don't call it, it can't run, so you have to call it each time.
Cut & paste.....
Why not paste your actual code here, some refactoring may help.
Edit after seeing actual code
I can't see the problem with your existing code. It is clear and you will know what it does in a year's time. I would keep it as it is. The answer you accepted will work, but it is obfuscating your code. You will have problems working out what you did and why you did it in when you come back to maintain your code in the future.
You could create a class containing an instance of the class test (composition) and implement its __call magic method. Something akin to:
class testWrapper
{
private $test;
function __construct()
{
$this->test = new Test();
}
function __call($name, $args)
{
call_user_func_array(array($this->test, 'some_method'), $args);
call_user_func_array(array($this->test, $name), $args);
}
}
You then call methods from the test class on the instance object of testWrapper.
You can further refine the logic in the __call method to only call some_method() based on the passed-in method name, etc.