I have a simple controller file StudentController.php
<?php
$data = array();
$data["firstName"] = $_GET["firstName"];
loadView("StudentView.php", $data);
?>
I have a even simpler view file called StudentView.php
<?php
echo $firstName;
?>
I have absolutely no idea how to implement loadView($view, $data) function. I want variables from $data in controller became available in view ($data["foo"] from controller became $foo in view)
I want achieve what is very easy to do in CodeIgniter but I have no idea how it is implemented. I tried to look into Controller.php and Loader.php in source files, but it was too messy for me to understand.
I don't want to use CodeIgniter or any other framework, I want to natively do in PHP.
If you're going to be building a large website to be used by the general public, a framework is generally a good idea for multiple reasons:
Properly unit tested - generally speaking, you can be confident that the core of your website is functioning as it's intended to
Community support - have questions and you can easily get answers; generally these frameworks are open sourced and usually actively developed by the PHP community
Secure - Framework developers are, well, framework developers; and they have been trained to write code with security as a top priority
However, this question has nothing to do with frameworks vs not, so I'll answer the question you asked with a very simple function:
function loadView($view, $data) {
extract($data);
ob_start();
require_once $view;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
You can chose to return the contents or print them directly, but that function should do what you need. I'm making no guarantees about the security of this code, and I have obviously done no error checking. But it should serve as a great foundation to get you started.
Related
I have been experimenting with Slim for a few days now and there is a lot that I like. However, there is one thing that nags me - when Slim is used to build a REST API it insists on putting everything into one single .php file - or even worse, a load of anonymous functions (one for each exposed REST method).
This works, that is not the issue. However, does it not mean that when used for building any but the most trivial of APIs you are imposing an unnecessary burden on the server by getting it to load and parse a potentially really big PHP file when only a tiny percentage of its code is relevant?
If yes, then it begs the next question - I am a newbie to micro frameworks - is there a micro framework that does things in a way that avoids this issue?
I'm unsure whether you are looking for a framework for a complete website or for an api alone. If latter I can recommend restler, which is a very simple, OO and stable package for developing API's.
On the other hand Laravel has built in resource controllers to ease the api development, it also has a very fast growing community.
If you're looking for both a website framework ánd an api framework in one, my guess is it will be very difficult combining that into one micro framework. Laravel/Symfony and other frameworks will eventually be needed especially if you expect growth in the project.
I made a REST API using AltoRouter:
http://altorouter.com/
I like the fact that after one route matches I can choose how to make the call, so I can point to the folder where I have all the REST controllers divided in several well organized files.
http://altorouter.com/usage/processing-requests.html
An example:
function rest_data($data, $format)
{
header("Cache-Control: no-cache, must-revalidate");
header("Expires: 0");
header('Content-Type: ' . $format);
if (is_object($data) && method_exists($data, '__keepOut'))
{
$data = clone $data;
foreach ($data->__keepOut() as $prop)
{
unset($data->$prop);
}
}
$options = 0;
$json=json_encode($data, $options);
echo $json;
}
$router = new AltoRouter();
$router->setBasePath('/rest');
$router->map('GET|POST','/', 'home#index', 'home');
$router->map('GET','/sample_users/all', 'sample_user#all', 'sample_users_get');
// match current request
$match = $router->match();
if($match && $match['name']=='home')
{
// write some intro
exit();
}
if($match)
{
$target=$match['target'];
list($class_name,$function_name) = explode("#",$target);
require($conf["src.path"].'/rest/'.$class_name.'.php');
foreach($_GET as $k=>$v) $match['params'][$k] = $v;
$controller = new $class_name;
$res = $controller->$function_name($match['params']);
rest_data($res,RestFormat::JSON);
}
If you are not so keen on the Slim PHP framework might I suggest something like Symfony ? Personally I like the way Slim works, and suits what I need to build right down to a T - however I can see your frustration with creating a RESTful solution. Symfony on the other hand breaks things up a little more so you have less fat controllers.
If Symfony isn't right for you I guess you could pull out a heavyweight ike Laravel?
I want to be able to call the CakeS3 plugin from the Cake Shell. However, as I understand it components cannot be loaded from the shell. I have read this post outlining strategies for overcoming it: using components in Cakephp 2+ Shell - however, I have had no success. The CakeS3 code here is similar to perfectly functioning cake S3 code in the rest of my app.
<?php
App::uses('Folder','Utility');
App::uses('File','Utility');
App::uses('CakeS3.CakeS3','Controller/Component');
class S3Shell extends AppShell {
public $uses = array('Upload', 'User', 'Comment');
public function main() {
$this->CakeS3 = new CakeS3.CakeS3(
array(
's3Key' => 'key',
's3Secret' => 'key',
'bucket' => 'bucket')
);
$this->out('Hello world.');
$this->CakeS3->permission('private');
$response = $this->CakeS3->putObject(WWW_ROOT . '/file.type' , 'file.type', $this->CakeS3->permission('private'));
if ($response == false){
echo "it failed";
} else {
echo "it worked";
}
}
This returns an error of "Fatal error: Class 'CakeS3' not found in /home/app/Console/Command/S3Shell.php. The main reason I am trying to get this to work is so I can automate some uploads with a cron. Of course, if there is a better way, I am all ears.
Forgive me this "advertising"... ;) but my plugin is probably better written and has a better architecture than this CakeS3 plugin if it is using a component which should be a model or behaviour task. Also it was made for exactly the use case you have. Plus it supports a few more storage systems than only S3.
You could do that for example in your shell:
StorageManager::adapter('S3')->write($key, StorageManager::adapter('Local')->read($key));
A file should be handled as an entity on its own that is associated to whatever it needs to be associated to. Every uploaded file (if you use or extend the models that come with the plugin, if not you have to take care of that) is stored as a single database entry that contains the name of the config that was used and some meta data for that file. If you do the line of code above in your shell you will have to keep record in the table if you want to access it this way later. Just check the examples in the readme.md out. You don't have to use the database table as a reference to your files but I really recommend the system the plugin implements.
Also, you might not be aware that WWW_ROOT is public accessible, so in the case you store sensitive data there it can be accessed publicly.
And finally in a shell you should not use echo but $this->out() for proper shell output.
I think the App:uses should look like:
App::uses('CakeS3', 'CakeS3.Controller/Component');
I'm the author of CakeS3, and no I'm afraid there is no "supported" way to do this as when we built this plugin, we didn't need to run uploads from shell and just needed a simple interface to S3 from our controllers. We then open sourced the plugin as a simple S3 connector.
If you'd like to have a go at modifying it to support shell access, I'd welcome a PR.
I don't have a particular road map for the plugin, so I've tagged your issue on github as an enhancement and will certainly consider it in future development, but I can't guarantee that it would fit your time requirements so that's why I mention you doing a PR.
I've found this script for converting wiki syntax to HTML in php and i've tried to integrate it into Codeigniter. it seems really easy to use. However, it's not working, and instead producing around 8 of these errors:
Message: Use of undefined constant LS_NONE - assumed 'LS_NONE'
I think this is because Codeigniter helpers are not a class but rather functions, and this bit of code is a class, or does this issue lie with something else? I've also tried to use it as a model without success.
It also seems horribly outdated (2007). Could somebody suggest a really simple alternative or maybe give an idea of how to convert this to a simple function if that is possible? It's a very short piece of code. I'm not sure how these constants work in relationship to a function versus a class.
I've given the Text_Wiki from Pear ago, but the use and complexity well exceeds both my requirements and knowledge :)
//Any help would be greatly appreciated
Loaded using:
$row = $query->row();
$content=$row->course_content;
$this->load->helper('wiki');
$content=explode("\n", $content);
$output = WikiTextToHTML::convertWikiTextToHTML($content);
$html=array_merge($output);
$data['contents'][]= $html;
$this->load->view('default/a',$data);
It looks like the script is actually a class. put it in the libraries folder and load it with $this->load->library(). That will allow it to properly initialize and define the constants that it uses.
something like:
$this->load->library('wikitexttohtml');
$this->wikitexttohtml->convertWikiTextToHTML($wiki_text);
in asp.net there are controls like grideview, menus, .....
how to develop a web control in php like an editor [html, jscript, ajax calls to server] it is used repeatedly and the improvement of control will be better if we can separate it?
First of, be aware that in PHP "control" and worse, "controller" means completely differently.
I've not used ASP, but I've used Delphi extensively, as well as Delphi for PHP, which does the same thing you are asking about (yes, in PHP).
Basically, you need some sort of framework to build this stuff on, as Johann said, you might want to use MVC, but you don't really have to.
Example of such a system (without MVC):
class TControl {
public $width=0;
public $height=0;
public $name='ControlN';
public function render(){
echo '<div style="width:'.(int)$this->width.'px; height:'.(int)$this->height.'px;"/>';
}
}
class TLabel {
public $caption='Label';
public function render(){
echo '<div style="width:'.(int)$this->width.'px; height:'.(int)$this->height.'px;">'.htmlspecialchars($this->caption,ENT_QUOTES).'</div>';
}
}
$label=new TLabel();
$label->width=200;
$label->height=24;
$label->caption='My label!';
$label->render();
In PHP you write all 'controllers' in plain HTML.
If you want 'controllers' that you use more often, then make functions for them, f.ex;
function list($array)
{
$output = '';
foreach($array as $item) $output .= "<li>$item</li>";
return "<ul>$output</ul>";
}
Now you got an 'list controller'.
ASP.net tries to mimic Windows Forms, this allows Windows Forms users to quickly get a website up and running. And as it mimics Windows Forms they created several preloaded user controls that you can insert into a web page. All these do is produce the styles, JavaScript and the HTML necessary to show the control on the client browser with your configured options. You could try to produce a similar effect in PHP , with .php that you include. For example creating a button.php and then including it where you want the button to be displayed.
But for simplicity I find that the MVC approach to development with PHP and a Framework is much more cleaner.
I'm having a terrible amount of problems with an XML parsing script leaking some memory in PHP.
I've made a solution by rewriteing my whole OOP code to non OOP, which was mostly database checks and inserts, and that seemed to plug the hole, but I'm curious as to what caused it? I'm using Zend Framework and once I removed all of the model stuff, there are no leaks.
Just to give you and idea how bad it was:
I'm running through some 30k items on the same number of files. So, one per file. It started out by using 5mb!!! or RAM, when the file itself was only about 20kb big.
Could it be those referencing functions that I've read about? I thought that that bug was fixed?!
EDIT
I found out, that the leak was due to using Zend Framework database classes. Is there a way to call a shutdown function after each iteration, so that it would clear the resources?
Its pretty dificult to answer this as we have no code to work with.
Revert back to the OOP version of your sources and create a small class like so:
abstract class MemoryLeakLogger
{
public static $_logs = array();
public function Start($id,$action)
{
self::$_logs[$id] = array(
'action' => $action,
'start_ts' => microtime(),
'memory_start' => memory_get_usage()
);
}
public function End($id)
{
self::$_logs[$id]['end_ts'] = microtime();
self::$_logs[$id]['memory_end'] = memory_get_usage();
}
public static function GetInformation(){return self::$_logs;}
}
and then within your application do the following:
MemoryLeakLogger::Start(":xml_parse_links_set_2", "parsing set to of links");
/*
* Here you would do the relative code
*/
MemoryLeakLogger::End(":xml_parse_links_set_2");
And so forth throughout your application, you will need to create calculations to gather the offsets for memory usages and time taken per action, once your script is completed just debug the information by printing it in a readable fashion and look for peaks
You can also use xdebug to trace your application.
Hope this helps