I was wondering, can you make a function or something, that looks for other function calls across the site? I think, that if there is a master page, you could include it at the very top and it should work sitewise.
But I have no idea how to do this.
Kind of like debug_backtrace();, but global. In other words, a function that does something with a function that has been called after this function.
Well, I see that you could do this with a specific call_user_func();, therefore track everything what's going on, but.. any dynamic way?
Thanks in advance!
Goal
The goal of this is to dynamically keep chain of called functions. So at some moment, for example, I require a value back from 3rd function in chain, so I can simply retrieve it with something like $calls[2]; // the stored returned value or an array containing info about function + returned value.
And it adds function data to chain on each call, where 1st call's $key = 0. So for debugging purposes, when my function fails which is x function in a row, I'd love to know information about previously called functions, maybe one has returned wrong value, resulting in error at some part later on.
It looks like you are looking for some AOP technique. You could write the weaved code to return immediately if some (global) flag (show trace) is not set, otherwise print the backtrace.
PHP doesn't support AOP directly but you can either patch the PHP core or use tools to create (transform the) code based on the AOP weavings. I haven't used it for PHP yet, so you have to google.
I don't believe there is, and I doubt if it would work and would be useful. Functions in turn call other functions, even the internal ones. Even the logging functions are functions themselves, so you end up with an enormous amount of information with which you can do virtually nothing relevant. If such a solution exists (it may), it won't be developed in PHP itself, but be a module that is loaded by or compiled in PHP.
If you want to log method calls to class instances, you could make some hook. You can make a class that implements __call. Then, for an instance you want to log, assign that instance to an instance of your log class, and assign that log class instance to the variable in which the original class was stored.
Then, each method call is directed to your class and you can log each call before you call the original method.
Give a try to diyism_trace.php:
http://code.google.com/p/diyism-trace/
Related
I have a master class, DBAPI which contains all the interaction with the database. It's not singleton per se, but is designed to only be instantiated once as $DBAPI.
When I alter the database, I obviously have to add functions to DBAPI to let the site use the new functionality, however, since there are a lot of different actions that can be taken, instead of including everything in a single massive class file, I've split them out by functionality/permission level as traits, and the DBAPI class file is dynamically created by adding traits flagged based off of permission level (read only, read-write etc.). Since the only time the file needs to be created is when new traits are added, I only create the class file if it doesn't exist for that specific user permission level, otherwise I use the already generated file. (If there's a better way to do this I'm all ears).
The issue I'm running into now is that if I add some functions in a new trait, the previously generated classes are obviously not aware of it, and I don't find out about that until I try to use the function in the code somewhere and it fails. It's pointless to write wrappers around every single function call made to check if it is a function first- is there some way to get the DBAPI class to do some action if code attempts to access a method it can't find?
for example, if code calls some function $DBAPI->newfunction() $DBAPI handles the exception itself, running some code that will attempt to update itself, which will cause newfunction() to run if it can be found.
(N. B. This architecture has a really bad code smell. I'm sure there's a better way to do this.)
PHP classes can implement the __call magic method that is used when there is no matching method name.
function __call( $name, $arguments ) {
// Code to run...
}
I'm trying to devise a plugin system for a simple web app I'm developing.
Each plugin begins with the function call register_plugin that contains that plugins info, like name, description, etc.
I want to be able to set a mode, say, to 1, and then have the ability to include the plugin file, have it call the register_plugin, and then EXIT the included script only. I know that I can stop execution with a simple return;, however, the register_plugin function is located in a different file, a class, so I can't simply call return because that will only end the function.
How can I do this?
Thanks.
As you already have outlined in your question, you would need to change the structure of your code and files to get this to work.
There is no magic kind of return that would not leave the function but the file or that would leave the function, then the file.
You need to re-arrange your code, add additional checks then to provide the functionality you're looking for.
I have been using a controller method post directly to perform some db and social network operations but im finding a few points of failure between it and the hardware — so I came up with the idea of storing all the request in a db table to be used as a queuing system instead so I can process them in my own time rather than real time
The thing I'm struggling with now is handling my requests . I know this isn't very MVC — but its quick fix.
How do I call another controller's method from within my process queue method? I have tried including the file and instantiating it — then passing it the variables i would have done from the web.
function process(){
$result = $this->mque->get_all();
include('post.php');
$get = new post();
foreach($result->result_array() as $item){
$get->index($item['rfid'],$item['station_id'],$item['item']);
}
}
but i get an error- when i call the normal index method- it runs fine but i get an undefined method error when call it through the instantiated class method- (this is my problem)
Message: Undefined property: post::$db
The why
I am setting the process queue method to run based on a cron job running at a set interval of time.
Originally everything ran to index method of post — but since post::index() can take 10-15 seconds to run and the reader is not multi threaded — someone could use the reader within 7 seconds and the script wouldn't have run completely.
Is there a better way of doing this rather than using my current process method?
update
there is two ways to do this- either use php to fopen/get from the web
or do it sprogramming using $class->method()- i would prefer to do this the first method but dont really see any option with the error i mentioned before
That's easy: you don't have one controller call another. As a rule, if you need something to exist in two different places, you have two options:
Have them both subclass the same object
pro: That way the method is already there
con: You can only subclass one thing, and you have to build your own class loading system (NOT GOOD)
Have a library (or model) which they both share
pro: The method can then be tested better (it is (or it was at one point) easier to unit test models than it is to test controllers), the code can be shared without a custom class-loading syntax.
con: This may involve a little refactoring (but it should be as easy as moving the code from the controller's method to a library's method and then simply calling the library in the public controller method).
Either one of those would solve your particular problem. Personally, because of how CI loads controllers, my preference is to create libraries.
CodeIgniter: Load controller within controller
Is this something that could help you out quickly? Check the bottom reply.
Working through several layers of an MVC architecture designed program, I find that I would like to have more information on a deeper layer's method return result, and that it's not always that I can anticipate when I'll need this information. And - for abstraction sake - I might not want that method outputting stuff to the application-specific log (that method could be used in a different program), or have a specific application dependent behaviour like other layers above.
For instance, in a given utility function I might have several pre-requisite checks before executing an action, that fail. If I return false on any of them, the caller doesn't know what happened. If I return false and log to the application log what happened, I'm bounding that function to application specific behaviour.
Question is: is it good/common pratice to implement a little class called MyResult and have it return the response status (ok/false), a message, an eventual integer code, and an object placeholder (array or object) where the caller could access the returned object? This MyResult class would be used throughout the whole system and would be a common "dialect" between all methods and their callers. All methods would then return an instance of MyResult, all the times.
Could you give an example? It seems a bit, but I can be mistaken, that you are having methods you are using statically (even if they are not implemented/called like that they could've been). The basic example of the table-object that can paint itself is called like so: $myTable->paint();. It can return a variable if it worked or not (true/false) but any other thing (like logging) is a function of table() and neither your calling method, nor the return value should have anything to do with that as far as I'm concerned.
Maybe I'm having a hard time understanding what situation you are going to use this for, but if you want to send messages around for some purpose that requires messages (or events etc) you should define those, but I don't see any merit in defining a default returnObject to pass around method-call results.
For errors you have two options: exceptions (that is: things you really don't expect to happen and should halt execution) and errors: expected but unwanted behaviour. The first should be left alone, the second can be tricky, but I'd say the object itself should contain a state which makes it clear what happened.
That's what exceptions are for. You don't have to over-do them like Java, but they exist because error codes suck.
If a framework does not offer a specific feature you need, there is no other way then that you take care on your own. Especially if you need something that runs cross the aims of the framework, so would never make it in.
However, many frameworks offer places in which you can extend them. Some are more flexible than others. So if possible I would look if you can still implement your needed feature as a type of add-on, plugin or helper code that can stay within the frameworks terrain.
If that is not possible, I would say it's always valid to do whatever you want to do. Use the part of the framework that is useful for you.
I am just getting into OOP and framework design. I have started by using the following three tutorials;
http://net.tutsplus.com/tutorials/php/creating-a-php5-framework-part-1/
http://net.tutsplus.com/tutorials/php/create-a-php5-framework-part-2/
http://net.tutsplus.com/tutorials/php/create-a-php5-framework-part-3/
This is the first framework I have tried to work with and because the tutorial is not aimed at complete novices I am finding myself having to reverse-engineer the code to see how everything works. The problem is I'm stuck.
First, I understand the basic concepts of the framework including the directory structure.
Second, I understand what the registry and database class are for (although I don't fully understand every function within them just yet).
My problem comes with the index.php, template.class.php and page.class.php files. I broadly know what each should do (although further explanation would be nice!) but I do not get how they fit together i.e. how does the index page interact with the template and page objects to actually produce the page that is displayed. I especially cannot work out in what order everything is called.
The index appears to me as:
require registry class
create instance of registry (don't quite get this bit - easier way to access database?)
store the database and template objects
creates new connection from the stored database object
choose the skin for the page
Then, and here is where I get lost:
build actual page via buildFromTemplates function (which I can't get my head round)
cache a database query
assign tab (i'm completely lost as to what a tag is!)
set page title
display content
Can anyone help break this down for me? I tried Zend before this but it was far too complicated, this one is more accessible but as you can still has me stumped (although I have started to understand objects FAR more by trying).
Thanks in advance.
Firstly I think they over complicated the implementation of the Registry pattern. I always used the following approach which is more straightforward (I'll print a simplified version of it).
class Registry {
protected static $_instances = array();
public static function add($instance, $name) {
self::$_instances[$name] = $instance;
}
public static function get($name) {
return self::$_instances[$name];
}
}
The Registry combined with the Singleton is just a mess.
Regarding the aspects where you got lost:
1. buildFromTemplates
Method accepts unlimited numbers of parameters func_get_args() as template file locations, either relative or absolute. If relative (as in skins/ not being part of the parameter send) overwrite the variable holding the name $bit with the absolute location. If the file exists read in the variable $content. Repeat until all method arguments are used and add the end result to the Page class.
2. Query cache
If the given query does not return a resource_id (which a database query should) it means the query didn't execute successfully and the method triggers and error. Otherwise save the resource_id in the property queryCache for later use. For example:
// assume $db is a reference to the database object and that this is the first
// query
$db->cacheQuery('SELECT * FROM whatever');
$results = $db->resultFromCache(0); // previous query resource_id
.... ahhh, forget it.
This is so messed up, rather recommend you start with some sane framework good for learning internal works. Like CodeIgniter, and move onwards when those concepts are clear.
This tutorial is full of wrong decisions, like errors instead of exceptions, tight coupling, custom template engine (where plain PHP would have sufficed) and more.
Even symfony, which is a big framework is not that hard to follow along the lines.
Ok, its taken me all of the last two nights and tonight (:-S) but I think I have an answer so I will post it to see if it helps anyone else.
I will start from the '//database connection' line
database connection is made
skin is chosen
'buildFromTemplates' function chosen from the 'template' class.
Set the parameter to the page you are trying to build. The layout of the page you wish to create should be stored under skins>templates>filename.
The constructer called when executing the template class will then initiate a new Page instance.
This buildFromTemplates function then takes the parameter aka the file name and then retrieves the content from the file. This will be stored in the $content variable.
the database query is then made and executs the cacheQuery function
the addTag function for the Page object you have instantiated is then called
the title of the page is then set
Finally,
the parseOutput function is called which runs the replaceBits, replaceTags and parseTitle functions. This replaces the respective code written with the page you are trying to create.
Finally the content is output to the page.