PHP . execute code only once at all , - php

I'm new to PHP and just started to learn it. There is this problem that I'm working on it for quite a time now but nothing seems to work.
well, the problem is that I have a piece of code for a web page and I need it to be executed only once. By that I mean the code must be executed when the very first client views the webpage and stop working for the second and other clients who view the page.
I have tried "include" and "required once" but these execute code once per run. I have also tried using session but it this case also the code executes once for each client.
And Also, yes I know I can use a flag and check database to make this work, but I wanna know that PHP has it handled or not
So I'm kinda stuck here.
We know that PHP is the server side language; therefore does it have any feature which executes a code once and stores the results in its global space?
Here is my code, I read data from excel and then I create my array of items.
// foreach row
// I read $col1 ..$col6 from excel for each row
new itemdata($col1,$col2,$col3,$col4,$col5,$col6);
class itemdata
{
public $item;
public $cat;
public $unit;
public $prec;
public $alarmType;
public $order;
static $items=array();
function __construct($item,$cat,$unit,$prec,$alarm,$order)
{
$this->item = $item ;
$this->cat = $cat;
$this->unit = $unit;
$this->prec = $prec ;
$this->alarmType = $alarm;
$this->order = $order;
array_push(self::$items,$this);
}
// And some methods for searching declared array 'items'
I need to execute this code once at all .
I appreciate your help.

Related

PHP Classes - How to call them properly

Here's what I'm pretty sure I can do, just don't know how to do it.
class My_Looping_Class {
public function __construct() {
$this->vars = new My_Vars_Class(); //maybe this goes here???
for($y=0;$y<=10;$y++) {
$this->do_loop();
}
}
private function do_loop() {
//in this loop the value of $x in My_Var_Class gets incremented each loop but I'm not exactly
//sure how to call it. Something like this????
$this->vars->x++;
}
}
class My_Var_Class {
public $x = 0;
}
class My_Looping_Class_Copy extends My_Looping_Class {
// Here I need to be able to read and echo the value of x in My_Var_Class each time it
//changes but again, I'm unsure of how to call it.
}
new My_Looping_Class_Copy();
Tried to post this with just the code above and it complained I didn't have enough details. So, here goes:
What I'm attempting to do is to write a web crawler similar to PHPCrawl. In PHPCrawl you basically set the parameters for the crawler (crawl depth, follow redirects, timeout, etc.), set the url, call a "go" function in the main class and it starts crawling pages. As it crawls each page it updates another class that contains all of the result variables, like response time, links found, etc. After it finishes each page crawl, through a class extension, you're able to access all of those variables and process them as you please. After that, it crawls another url it found and updates the result variables.
I tried reading through the code but got lost pretty quick as to how the author did this. The code above is just a very basic example of how PHPCrawl works.
Here's a link to the PHPCrawl example code: http://phpcrawl.cuab.de/example.html What I'm trying to duplicate is the handleDocumentInfo($DocInfo) function.
If I understand you correctly, here's an example of how you can get the value of a property of one class and use it in another one. Extending that other one, instantiating it, and getting the new value of the property:
class My_Looping_Class {
public $xCopy;
public function __construct() {
$varClass = new My_Var_Class();
$this->xCopy = $varClass->x + 10; // Here i add 10 to this class propert 'xCopy'. Loop or do whatever you want with it instead.
}
}
class My_Var_Class {
public $x = 33; // Just some number as an example.
}
class My_Looping_Class_Copy extends My_Looping_Class {
}
$loopClassCopy = new My_Looping_Class_Copy();
echo $loopClassCopy->xCopy; // Should output 43 (33 + 10)
Or see this working example.

How to properly recall a function using custom MVC

Hi and good day to you all..
I'm new to MVC's/model-view-controller frameworks. I've made my own by reverse-engineering a custom MVC framework I've got from a friend of mine, so far it's all going good and smooth until I got to this part where I need to recall a function inside the function it self.. I'm currently creating a binary tree website and need to output values inside the table, what I'm trying to do is call a function and fetch all values and put them inside an array for later referencing.
This is my code in the model folder.
public function getGenealogy($parent) {
$this->db->sql('SELECT * FROM accounts WHERE sponsorUpline = ?');
$this->db->bindValue(1, $parent);
$this->db->execute();
while($row = $this->db->fetch()) {
echo $row['serialNumber'];
$this->getGenealogy($row['serialNumber']);
}
}
And this is my code in the controller folder
public function index() {
$memberAccounts = $this->db->getMemberAccounts();
$getDirectReferal = $this->ddrs->getDirectReferal();
$genealogy = $this->bg->getGenealogy($_SESSION['activationCode']);
$data = [
'memberAccounts' => $memberAccounts,
'getDirectReferal' => $getDirectReferal,
'genealogy' => $genealogy
];
$this->view('dashboards/dashboard', $data);
}
As you can see, I'm trying to call the function inside of the function but what happens is that it doesn't call it self, I tried doing the same method but not with MVC and it works fine.
So my conclusion is there's something wrong about my code that I can't seem to grasp.
Also it outputs the children twice but with same values.
This is my database.
This is the output.
.
Any ideas or help would be appreciated.

Concrete5 MVC parent::save() having trouble finding database insert function, how to save to database

I am editing a concrete5 add-on and am trying to figure out how the program is saving values to the database. The following function is where the database save is happening but I am not sure where the "parent::save()" function is.
protected function SaveRecord() {
$func = 'jso'.'n_encode';
$this->errors = is_array($this->errors) ? $func($this->errors) : $this->errors;
$this->effectiveDate = is_numeric($this->effectiveDate) ? date('Y-m-d', $this->effectiveDate) : $this->effectiveDate;
$this->expirationDate = is_numeric($this->expirationDate) ? date('Y-m-d', $this->expirationDate) : $this->expirationDate;
//var_dump($this); die();
parent::Save();
// a bit hacky, but we are saving the errors as JSON, and we might need to access them later.
$this->errors = (array) json_decode($this->errors);
}
I have followed the class up to its parent and it does not have a save function. I followed the parent up to its parent until I found a save function in the "adodb" class, but die() never happens when put in this function. Please help me figure out how I am supposed to save values in Concrete5 to the database! (More of my code at: https://stackoverflow.com/questions/26940176/concrete5-add-on-extension-save-value-to-database).
#CaitlinHavener Your SaveRecord method should be like this.
public function SaveRecord($data){
$data['my_array'] = serialize($data['my_array']);
parent::save($data);
}
refer this link concrete5 document

How to convert an existing PHP library file so it can be used in a CakePHP framework?

I have this library in PHP non-Cake format, the usual PHP scripting which currently works like a charm. I need to use this in a Cake framework. The library file is as follow: (example extracted)
<?php
// REST API functions
function sendAction($itemurl, $itemimageurl, $sessionid, $userid, $rating=""){
global $someapiwebsiteURL, $apiKey, $tenantId;
$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
.....
................
}
//Codes extract
?>
I've come across a few ways of doing it. Currently confused, how am I going to place this library file into my Cake framework?
App::import()
Datasource
The functions in the library file above (I supposed it'd be used in one of my Controllers to render the data outputting through the view).
Currently working in a non-Cake framework structure, the view page is such as: (example extracted)
<?php
// my view page
$viewResponse = sendAction($itemdescription ,$itemurl , $itemimageurl,$sessionid,$userid);
//sample code only
?>
Both the files are working fine. The logic of putting it in a CakePHP framework is the problem here. Anyone may suggest "the" way of doing this without over-strenuously working on a data source? If we have to use a data source in App/models/datasources/, how exactly is the structure of it? Like, e.g., in datasource file, do we include the library functions? or is it some generic ReST datasource file which can be found here: CakePHP ReST datasource . I've gone through the cookbook chapter on datasource and understand we have to define the datasource in our database.php, but if someone is certain about their way of accomplishing it either using datasource or app::import() method, please share with more details?
UPDATE:
Hi Lionel!, thanks for filling up. Well, actually users will click on view action: function view (){} in my foods_controller. I'm appending some scripts here to include my view function in my foods_controller so maybe it may help you to help out easier. Thanks..
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
$this->set('food', $this->Food->read(null, $id));
}
The view action triggers the send_action function, (each time a user clicks on view page on foods controller). So each time, a user clicks on view action, his (dynamic variables): userid, sessionid, that page's itemid, url, itemdescription; (timerange value is a static string value "ALL"), and if any (etc.), so far only these values are available: Will be used as the "parameters" in the Send Action function. What you wrote is close to what the codes can do. You're right. Except we should include the Send Action function inside the view() in foods controller?
If we look at dynamically filling in the variables mentioned in the point above, could you modify your second code (the code from your product_controller, e.g.) so it also works to receive the variables dynamically? (as you asked in the last update: how to get the parameters..)
Just to make it clear.
A user views the page. The send action collects data and send to the API. (as we've already done by calling the function in the library the (ACME.php). *just waiting for your update if possible, thanks.
In the function view() of the foods controller: there's also an additional calling. The (2)second calling which is this:
$recommendResponse = getRecommendations("otherusersviewed", $itemId, $userId);
The second calling calls the ACME.php library file in which there consists the (2)second function that retrieves data, here it is: (it's in working order, but just needs to be changed into a public static function like you did for the (1)first function. Could you help to modify this code too, please?:
function getRecommendations($recommendationType, $itemId, $userId){
// sample code similar to the first one.
}
That's all to it. It seems quite simple in the normal PHP format, and it works easily, but getting it on an MVC framweork is a bit challenging for some, a lot for me. Thanks for helping out, Lionel. :-)
P.S. Hi Lionel, I notice something missing in the library after changes? Look originally we have this:
$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
Look, the variables for $SomeWebsiteAPI and $SomeApiWebsiteURL are different. Did I miss out something? or you have modified so it is more efficient ? I see that the variable named $SomeWebsiteAPI is modified to become variable called $link ? and variable $SomeApiWebsiteURL is changed to the named variable, $url, am I right ? .. thanks.
Thanks, best regards. John Maxim
To me, if I have this piece of code, I would first wrap it into a static (or normal) class, and named it ACME, then I will move the acme.php into /apps/libs/acme.php. Then in the controller, I will use App::import('Lib', 'acme'). This action do nothing but just requiring the file, so you can just use it instantly by calling ACME::sendAction(...).
And regarding the global thing, you might just need to declare a static (or normal) class, then define the shared variables as part of the class properties, so you can share them among all the functions in the class.
For example, this is the /app/libs/acme.php
class ACME {
private static $someapiwebsiteURL = "http://thewebsite/api/1.0/";
private static $apiKey = "0010KIUMLA0PLQA665JJ";
private static $tenantId = "THE_TENANT_NAME";
/**
* Simple builder to build links from array of $params
*
* #param string $url The api url
* #param array $params The given parameters
* #return string built url
*/
private static function BuildLink($url="", $params=array()) {
$link = $url;
foreach($params as $k=>$v) {
$link .= "&$k=$v";
}
//Replace the first & to ?
$link = preg_replace("/&/", "?", $link, 1);
//Not sure if we need URL encode here, please uncomment this
//if the API could not work.
//$link = urlencode($link);
return $link;
}
public static function SendAction($action, $itemId, $itemdescription, $itemurl, $itemimageurl, $sessionid, $userid, $rating="") {
$somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$action, array(
"apikey"=>self::$apiKey,
"sessionid"=>$sessionid,
"userid"=>$userid,
"tenantid"=>self::$tenantId,
"itemid"=>$itemId,
"itemdescription"=>$itemdescription,
"itemurl"=>$itemurl,
"itemimageurl"=>$itemimageurl,
/**
* Assuming your API smart enough to only use this value when
* the action is "rate"
*/
"ratingvalue"=>$rating
));
$xml = simplexml_load_file($somewebsiteAPI);
return $xml;
}
public static function GetRecommendations($recommendationType, $itemId, $userId) {
$somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$recommendationType, array(
'apikey'=>self::$apiKey,
'tenantid'=>self::$tenantId,
'itemid'=>$itemId,
'userid'=>$userId
));
$xml = simplexml_load_file($somewebsiteAPI);
return $xml;
}
}
And in your controller
App::import('Lib', 'acme');
class FoodController extends AppController {
//Food is plural already I assume? You can just use
//food, should be ok I think, else it will be weird
//to use /foods/view/?
var $name = "Food";
var $uses = array("Item", "Food");
function view($id="") {
//We accepts only valid $id and $id > 0.
//Take notes that this $id will be a string, not int.
if (ctype_digit($id) && $id > 0) {
//I don't know how you would gather the information, but I assume you
//have a database with the information ready.
//I assumed you have an `items` table
$item = $this->Item->findById($id);
$sessionid = "00988PPLO899223NHQQFA069F5434DB7EC2E34"; //$this->Session->...?
$timeRange = "ALL";
$userid = "24EH1725550099LLAOP3"; //$this->Auth->user('id')?
if (!empty($item)) {
$desc = $item['Item']['description'];
$url = "/foods/view/".$id;
$img = $item['Item']['img'];
$viewResponse = ACME::SendAction("view", $id, $desc ,$url, $img, $sessionid, $userid);
$this->set('food', $this->Food->read(null, $id));
}else{
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
}else{
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
}
}
Edit
The code has been filled up, and of course, without any warranty :). I personally don't really like to have long arguments in a function (like SendAction, error prune), rather use shorter one like the $params in ACME::BuildLink. But just to respect your code, I didn't modify much on the SendAction method.
Then I'm not too sure how you would make use of this code, so I assumed you have a ProductsController, and somehow the user trigger url like /products/send_action/. If you can provide more information, then we would be able to help out.
Edit Again
I have modified the ACME class, as well as the controller. Yea I do miss out some variables, but I had added them back to the updated code.
Not too sure if it would work (perhaps typo), you can just modify the code if it doesn't work for you.
And for personal conventions, I usually capitalize methods which are static, like ACME:GetRecommendations or ACME::SendAction.
Oh yea, I better stick back to the variables you used. Sorry for modifying them, just I don't like long names :)
And btw, the RoadRunner's ACME Corporation? Lol!
Cheers
Lionel

mysqli superglobal connection object, more than one connection at time

I've been using this solution to get a superglobal mysqli connection:
class blst_db {
private static $mysqli;
private function __construct(){} //no instantiation
static function cxn() {
if( !self::$mysqli ) {
self::$mysqli = new mysqli(...);
}
return self::$mysqli;
}
//use
blst_db::cxn()->prepare(....
I found it here and it was working fine but when I try to get two connections at the same time I get an error. For example, I've a class that runs a query like this one:
$query_points = blst_db::cnx()->prepare('SELECT point_id FROM points WHERE id=?');
$query_points->bind_param('i', $this->id);
$query_points->bind_result($point_id);
$query_points->execute();
while ($query_points->fetch()) {
$point = new blst_point ($point_id);
$points[] = $point; }
I'm creating various objects inside the while statement and that objects constructor runs another query each time (another $query=blst_db::cnx->prepare(...)) and that's the one that is not working and I can't find the problem. If I change the code and create an array inside the while statement and then, after closing that query, I create all the objects inside a foreach I get no problem but I don't like that solution.
Thank you!
I found the problem. I have to store the results from the first query so I can run the rest inside it. I just added:
$query_points->store_result();
after the execute() call and then I made a free_result() before closing the $query_points and it's working perfectly.
I've found the solution here.

Categories