I have a php file that creates a json output. my problem is that i will need lots of functions that return json data. For example:
i will need to fetch a list of all customers in a given db;
I will need to fetch all vehicles from a given customer;
i will need to fetch all data from a given vehicle
and so on. At this point i can have all this working if each function is in a separate php file. The complexity of this is only going to increase and i dont want to have lots of files cluttering the file system. Is there a way around this? any practical example would be appreciated
Sure. If you have one function for each type of action, like this:
function action_hello_world() {
echo "Hello, world!";
}
function action_hello() {
echo "Hello, {$_GET["name"]}!";
}
Then create an array of valid actions:
$valid_actions=array("hello_world", "hello");
Then we have a GET parameter called action:
$action=$_GET["action"];
We check to make sure it's valid...
if(!in_array($action, $valid_actions)) {
die("Invalid action.");
}
Then we call the correct function:
$function_name="action_$action";
$function_name();
Related
The question is one page will receive the GET data in 4 second interval and i have to display the parameter value in another page with updated value.It is just for display and no need to store the value.
I have tried it with the following code:datareceiver.php
<?php
require 'localStore.php';
if(isset($_REQUEST['name'])){
localStore::setData($_REQUEST['name']);
}
?>
localStore.php
<?php
class localStore{
private static $dataVal = "";
public static function setData($data){
self::$dataVal = $data;
}
public static function getData(){
return self::$dataVal;
}
}
?>
display.php
<?php
require 'localStore.php';
header("Refresh:2");
echo localStore::getData();
?>
How i can show the data in 'display.php' page, because the above 'display.php' prints blank on the page. I tried also the global keyword concept and the PHP magic _construct(), _get() and _set() by searching in google and going through stackoverflow. but it was difficult to understand since i am not a PHP guy. t was terrible for me to use these _get(),_set() and _construct().
PHP doesn't work like this. You have to store your data somewhere anyway. Script2 knows nothing about data recieved by script1. When you construct your localStore object it doesn't have access to properties of another object constructed by another execution, cause your datareciever object was destructed immediately after script end. You can check it usind __destruct() method
So, you need some storage to keep recieved by script1 data until script2 wants to display it. Most commonly used ways are: mysql DB, file and queue, say Rabbit.
The simpliest solution is
const FILE_NAME = 'tmp/anyname';
public static function setData($data){
return file_put_contents(self::FILE_NAME, serialize($data));
}
public static function getData(){
$str = file_get_contents(self::FILE_NAME);
return unserialize($str);
}
This has probably been asked before, but I couldn't find the answer to my question with some preliminary searches, so here it is:
A very simple example of my current method of injecting PHP variables into HTML is as follows:
HTML (file.php):
<tag><?php echo $variable; ?></tag>
PHP:
$variable = "value";
ob_start();
include "file.php";
$results = ob_get_clean();
This achieves the correct result just fine, but it annoys me every time that I have to copy and paste those three lines to get variables injected into my HTML files. There's a chance I might want to change the details of this injection functionality at a later date, and it's currently scattered in a couple hundred locations throughout my code.
In a perfect world, I would move those three lines to a separate function that takes the file path as an input, and returns the "compiled" result. However, the function would then no longer have access to the calling scope, and I would have to pass the variables in as another input. The only thing I'm able to think of for doing that is:
function injectVariables($filePath, array $variables)
{
//Built-in PHP function, extracts array key => value pairs into variable $key = value pairs in the current scope
extract($variables);
ob_start();
include $filePath;
return ob_get_clean();
}
That certainly gets the job done, and it will be what I implement if there aren't any better solutions, but it seems less than ideal to me. It involves creating an array every time this runs, just to loop through it and extract all the variables, which just feels a bit wrong to me.
Does anyone know of any other methods that might work?
Not really sure what you are asking, but here is my answer
I don't know the structure of your code, but I hope you are using a MVC approach (or at least something which deals with classes) so that you can do the following:
In your main controller, you create a class variable like viewData which will be an array. And you put in it everything you want
$this->viewData['username'] = $username;
$this->viewData['myArray'] = array('foo' => 'bar');
$this->viewData['menuSubview'] = 'path_to_menu_subview.php';
Then, you create a render function.
public function render()
{
extract($this->viewData);
ob_start();
include("myfile.php");
return ob_get_clean();
}
And in myfile.php (with the HTML) you can simply do what you used so far
<div id="menu"><?php include($menuSubview);?></div>
<p><?=$username;?></p>
<p><?=$myArray['foo'];?></p>
The whole code can be something like this.
class Something {
protected $viewData;
protected $viewFile;
public function logic()
{
$this->userProfile();
echo $this->render();
}
public function userProfile()
{
$this->viewData['username'] = 'John The Ripper';
$this->viewFile = 'myFile.php';
}
public function render()
{
extract($this->viewData);
ob_start();
include($this->viewFile);
return ob_get_clean();
}
}
Here's a simplified class that stores data and allows for recursive rendering of files that all have access to the save data form the initial instance.
class View {
// view data
protected $_data = [];
/**
* Set view data
*/
public function __set( $key, $value )
{
$this->_data[ $key ] = $value;
}
/**
* Get view data
*/
public function __get( $key )
{
if( array_key_exists( $key, $this->_data ) )
{
return $this->_data[ $key ];
}
return null;
}
/**
* Render view file
*/
public function render( $file )
{
if( is_file( $file ) )
{
$view = $this;
ob_start();
include( $file );
return ob_get_clean();
}
return 'File not found: '.$file;
}
}
Just use the variable $view inside your included files to access the data in the class, or render() another partial file that can do the same thing, and so on.
// Bootstrap a View instance and add some data
$view = new View;
$view->dataOne = 'valueOne';
$view->dataTwo = 'valueTwo';
// Render main template
echo $view->render( 'template.php' );
Inside template.php
<header>
<?= $view->render( 'header.php' ) ?>
</header>
<h1><?= $view->dataOne ?></h1>
<p><?= $view->dataTwo ?></p>
Nothing is wrong with your injectVariables() function, it is in fact a good idea.
You shouldn't have performance impact anyway (If this is your main concern your are doing premature optimization !)
Your view (HTML) shouldn't know about the internal of your application. (You split responsability - this is a huge subject that I won't talk deep)
You know if something end-up into $variables it has been build/formatted or is revelent to be display for $filePath.
In complex system you may end up with a variable with a pdf generator, why would the HTML want that? The only purpose of the HTML is to DISPLAY HTML data.
Some variables from your logic will end-up in $variables almost every time such as session informations (Who is currently logged), for your case this is normal.
In the perfect world if you put a class into $variables it should be designed only for purpose of your HTML even if it is almost the same object as your logic.
As an exemple I designed a Session class in my logic. It does have method such as Logout() and EnsureIsAlive() as well as field such as FullName. FullName is going to be use by my HTML because I want to display it in the header of my page.
I should have a Session class for the HTML that only contains a FullName field because the HTML has only one job and is it to display data. Login() and EnsureIsAlive() are specific for the logic and aren't related at all with displaying data.
In reallity time is always a constraint and because you are writing all by yurself from scratch you may end-up just sending the logic Session class into $variables.
Design note : I'm a C# programmer and we always use class over array to pass parameters as a good pratice and it does affect the exemple about how to pass FullName to your HTML. In your case, instead of creating a class dedicated for the HTML you could also create a simple array :
$variables['Session'] = array('FullName' => $mySession->fullName).
That way you still avoid your HTML to have access to the unrelated method specific for your logic. I'm not sure if it is a good pratice in php...
Keep context variables clean
If you do call injectVariables() more than once (for different $PathFile) you may not want the same variables.
One injectionVariables() could be for a widget, another for a complete complete page.
Why would a TimeWidget need your totalInvoice variable?
You also have the ability to prepare multiples $variables at the same time because each injectVariables() will have his own parameters.
I'm not up-to-date but I know phpBB template system use (back near 2000) the exact same pattern as your injectVariables()).
You wrote that each of your page do call injectVariables(), you could also (but it may be complex) do it only in one file - like php frameworks.
Framework handle HTTP requests into one specific file
(eg. http://yoursite.com/hello/world or http://yoursite.com/login would call (internaly) http://yoursite.com/index.php?page=hello&subpage=world and http://yoursite.com?page=login).
Then this page (index.php in my exemple) would include a specific file (controller) according with his GET parameters ($_GET['page'] and $_GET['subpage']).
The controller job would be to fetch data, apply logic then fill $variables.
Then index.php will call injectVariables() with the releated HTML.
I'm creating a website and somewhere in the code I need to query for a user attribute (ex:account state) and in the same row I have the reason, case is account state is "suspended".
I'm trying to minimize the requests to the database, so I created a function to verify account state.
function getAccountState($userid,$reason){}
What I am trying to do is if account state is "suspended" I would change the $reason to "the database reason".
I've already done that but if I change the $reason inside the function, outside the function it will not change.
I searched for "php pointers" on google but I think there is not such thing.
Is there a way to do this? Other way I'll just make another database request...
You could of course pass the variable by reference but as you don't seem to need it, I would just return it from the function:
function getAccountState($userid){
// your code
return $reason;
}
and call it like:
$reason = getAccountState($userid);
If you want to stay your code as it is now, you could pass the variable by reference:
function getAccountState($userid,&$reason){}
^ like so
You could consider passing it in by reference. Or perhaps just changing the function to return the correct information.
In the definition of functions you can tell that $reason argument is passed by reference, not value. To do so, use & in front of variable:
function getAccountState($userid,& $reason){}
You are looking for references, in PHP terminology, not pointers.
They work this way :
function getAccountState($userid, &$reason){ // Notice the &
$reason = "database locked"; // Use it as a regular variable
}
getAccountState(12345, $reason); // Here, it is written as a regular variable, but it is a ref.
echo $reason; // echoes "database locked"
I have a page named ChangeApprovalInfo.php - It has a function called Row_Rendered as follows;
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
}
Echoing $RecordOwner gets me the data I will need for a sql query on another page....
I have another page called ChangeApprovalEdit.php - This page has
<?php include_once "ChangeApprovalinfo.php" ?>
at the top of the file.
ChangeApprovalEdit.php has a function where I need the $RecordOwner variable as defined in ChangedApprovalInfo.php
If I add "echo $RecordOwner" on the ChangeApprovalEdit.php page, I get an error saying it's an unknown variable. My understanding is that I need to "make it global" or some such business. I know very little about PHP and the pages I am editing are long and complex. (to me, at least)
What do I need to do? I know that the information I have provided might not be enough to answer the question. I don't know enough to even know exactly what I need to ask. If more information is needed, I will edit and follow up.
pastebin of the files
ChangeApprovalInfo.php = http://pastebin.com/bSRM1wwN
ChangeApprovalEdit.php = http://pastebin.com/AStG9pqb
EDIT:
Changing Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
Don't echo variables from functions, which just outputs them to the standard output. return them from the function so you can use the value elsewhere as well.
function Row_Rendered() {
$RecordOwner = $this->RequestUser->CurrentValue;
return $RecordOwner;
}
Then instead of
$obj->Row_Rendered();
use
echo $obj->Row_Rendered();
and if you want to use the value elsewhere, use
$value = $obj->Row_Rendered();
You can do a couple of things:
First, you can return $RecordOwner from the function, and store its value in a variable. This method is usually preferred.
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$RecordOwner = $this->RequestUser->CurrentValue;
echo $RecordOwner;
return $RecordOwner;
}
// Store it in a variable when calling the function.
$RecordOwner = Row_Rendered();
Or, you can make it global inside the function:
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
echo $GLOBALS['RecordOwner'];
}
You can use the $GLOBALS superglobals array, like this:
function Row_Rendered() {
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
However, you should not do that. Instead, refactor your application so that the view in ChangeApprovalinfo.php just contains a function, which is then called with the appropriate parameters.
EDIT: Chaning Row_Rendered to this seems to be more effective. I'm having trouble seeing WHERE I can later echo this variable... but I'm getting somewhere with this...
function Row_Rendered() {
// To view properties of field class, use:
//var_dump($this-><FieldName>);
$GLOBALS['RecordOwner'] = $this->RequestUser->CurrentValue;
}
I feel compelled to write another answer to this update. Let me demonstrate the use of globals as seen from outside that function:
$obj->Row_Rendered();
$obj->foobar();
echo $GLOBALS['RecordOwner'];
Quick, what will be echoed and where does that value come from? Well, it depends on what $obj-foobar() does. Maybe it changes the global variable. Maybe it doesn't. Who knows if the variable has been set at all? How would you trace back what happened exactly without adding a debug line after every single function call?
And that's just three lines of code. Imagine that in an application of any complexity.
Now, the same thing if I return the value from Row_Rendered:
$owner = $obj->Row_Rendered();
$obj->foobar();
echo $owner;
If the Row_Rendered method is behaving as it should (returning the owner), this code is very predictable. If you do not follow this pattern, you'll have a hell of a time getting anything done when the application grows to any halfway complex size.
Set the variable as global from within the function
$my_global_var = "old value";
function doing_stuff(){
global $my_global_var; //this will use the global variable instead of creating a local one
$my_global_var = "new value";
}
echo $my_global_var;//returns "new value"
I'm looking for the "best practice" way to achieve a message / notification system. I'm using an OOP-based approach for the script and would like to do something along the lines of this:
if(!$something)
$messages->add('Something doesn\'t exist!');
The add() method in the messages class looks somewhat like this:
class messages {
public function add($new) {
$messages = $THIS_IS_WHAT_IM_LOOKING_FOR; //array
$messages[] = $new;
$THIS_IS_WHAT_IM_LOOKING_FOR = $messages;
}
}
In the end, there is a method in which reads out $messages and returns every message as nicely formatted HTML.
So the questions is - what type of variable should I be using for $THIS_IS_WHAT_IM_LOOKING_FOR?
I don't want to make this use the database. Querying the db every time just for some messages that occur at runtime and disappear after 5 seconds just seems like overkill.
Using global constants for this is apparently worst practice, since constants are not meant to be variables that change over time. I don't even know if it would work.
I don't want to always pass in and return the existing $messages array through the method every time I want to add a new message.
I even tried using a session var for this, but that is obviously not suited for this purpose at all (it will always be 1 pageload too late).
Any suggestions?
Thanks!
EDIT: Added after I caused some confusion with the above...
The $messages array should be global: I need to be able to add to it through various different classes as well as at the top-level of the whole script.
The best comparison that comes to mind is to use a database to store all the messages that occur at runtime, and when it's output-time, query the database and output every message. The exception to this comparison is just that the lifetime of the $messages array is the page load (they accumulate during page load, and vanish right after).
So, for example, say I have 10 different actions running one after the other in the script. Each one of these actions make use of a different class. Each one of these classes should be able to post to $messages->add(). After all 10 actions have run, it's "output time", and the $messages array can contain up to 10 different messages which were added via all the different classes.
I hope this clarifies it a bit.
I'm not exactly clear about what you want to do, but a good way would be to simply use a private variable:
class messages {
private $messages = array();
public function add($new) {
$this->messages[] = $new;
}
public function output() {
// Whatever; e.g. a foreach loop that echoes all the messages
}
}
I think you need either a instance field.