How can i access a variable outside that function in codeigniter - php

I am sorry for asking this basic level question. I have fetched some data from DataBase and stored it to a variable inside a function, and wanted to get the value of that variable outside the function?
public function getemailData()
{
$email_id_investors = $this->db
->select('value')
->get_where('common_email_settings', ['name' => investors_email])
->row()->value;
}
I wish to get the value of the $email_id_investors outside the function. Again I am apologizing for this basic question
Database table name - common_email_settings
fields are Id, title, name, value
1 Greeting Mail, greeting_email ,Greetings#investorsloanservicing.com
2 Loan Service Mail, loan_service_email ,LoanServicing#investorsloanservicing.com
3 Processing Mail, processing_email ,processing#investorsloanservicing.com

To strictly answer the question, you could store the value in a scoped global $this variable, though I don't know why you wouldn't just query the function and have it return a value.
public function getemailData($investors_email)
{
$this->email_id_investors = $this->db
->select('value')
->get_where('common_email_settings', ['name' => $investors_email])
->row()->value;
}
// then in another function called later in the chain, you can grab it
public function doSomethingElse() {
$investors = $this->email_id_investors;
}
It's probably better just to create a getter function for that variable.
This doesn't look useful given your scenario. This might be useful if the variable you're storing is something processor intensive (and you're using $this like a cache), you need to access it in multiple functions called during a given state, and you don't want to rewrite your function chain to accept this parameter (so as to pass it along). However, that is a clear sign you need to refactor your logic and make it more flexible (pass object or arrays rather than single variables for example).

You are not returning your variable.
Try returning your variable like this,
public function getemailData()
{
$email_id_investors = $this->db
->select('value')
->get_where('common_email_settings', ['name' => investors_email])
->row()->value;
return $email_id_investors;
}

function getemailData($name)
{
$email_id_investors = $this->db
->get_where('common_email_settings', ['name' => $name])
->result()[0];
return $email_id_investors->value;
}
This one worked for me. I have given this function in the common model page and called this on other pages.Thank you for your help
$email = $this->common->getemailData('account_email'); -> getting data in this variable
echo $email;
// exit();

Related

Exception - Call to a member function get_record( ) on NULL

I'm trying to use the moodle Data Manipulation API to get the grades from students to analyse. But when I use the function get_record() inside of another function that I've created I get the message of the tittle. I don't know why the fuction works in the main and don't work inside a function.Any idea? I'm new in php and moodle manipulation, so take easy on me.
<?php
function get_all_quiz ($courseid) {
$quizesid = [];
$quiz = $DB->get_record('moodle.quiz', array('id'=>$courseid));
$quizesid = $quiz.id;
return $quizesid;
}
global $DB;
define('CLI_SCRIPT', true);
require '../../var/www/moodle/config.php';
$coursetest = 3;
$studentgrades = [];
$quizes = get_all_quiz($coursetest);
?>
There are a few things you need to fix in this function:
You need to add global $DB; inside the function
The quiz database table is called 'quiz', not 'moodle.quiz' (Moodle config handles connecting to the correct database)
PHP uses '->' operator to access object properties, not '.' (which is used for concatenation), so it is $quiz->id not, $quiz.id
If you are wanting to return all quizzes, you should call $DB->get_records(), not $DB->get_record() (which returns just 1 record and outputs debugging warnings if more than one is found).
If you want the quizzes for a particular course, then you should match the 'course' field in the quiz record, not the 'id' field (which is the ID of the quiz, not the course).
So the function should probably look like this:
function get_all_quiz($courseid) {
global $DB;
return $DB->get_records('quiz', array('course' => $courseid));
}

How can I write a function which has lots of arguments better?

I have a function like this:
public function myfunc ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8) {
// do something
}
See? My function gets 8 arguments. Yes it works as well, but you know, it's ugly kinda ..! Isn't there any better idea? For example passing just one array contains all argument. Is it possible? or even something similar.
I do it this way..
$params = [];
put things in params..
$params[] = $a;
$params[] = $b;
pass the array to function
myFunction($params);
The function accept array as arg like, definition:
public function myFunction($params = []){}
Pass something in, and var_dump to check for yourself...
OK, now I know that it's an SQL operation you're doing then the best approach would be an associative array (assuming PDO and prepared statements).
public function myFunc (array $data)
{
// Using 3 values for example!
$stmt = $this -> pdo -> prepare ("INSERT INTO TABLE thisTable (
col1,
col2,
col3
) VALUES (
:val1,
:val2,
:val3
)");
if (false !== $stmt execute ($data))
{
return $stmt -> rowCount ();
} else {
return 0;
}
}
You'd call it with an array with the correct parameters in it:
$success = (bool) $obj -> myFunc (["val1" => "First value to insert",
"val2" => "Second value to insert",
"val3" => "Third value to insert"]);
It depends whether myfunc belongs to an exposed api or not (i.e.: public)
If it is public, the signature must break when you update the underlying model (your insert query), otherwise errors will be committed on the client-side.
With an array, you're losely mapping your Model to your Application, and you'd just expect programmers to send you the right values. With a tight/restricting mapping, this kind of error cannot happen.
I think that if you're saving an item in the database, you actually need all these fields. It is unelegant indeed, but it's not an anti-pattern as none of them are optional. And even if one or two were, it would not be a concern.
What you could do to improve your api is either:
If there are situation where you need to pass only a few of the parameters (i.e. most are optional or depend on a particular scenario) then you could specialize the method into separate functions. But PHP not accepting function polymorphism is quite a pain in the neck for this kind of things; you'd have to name the methods differently.
public function myfunctosavedatainaparticularcase ($arg1, $arg2, $arg3, $arg4)
// do something
}
public function myfunctosavedatainanotherparticularcase ($arg5, $arg6, $arg7, $arg8)
// do something
}
Use an object model mapper. For example, suppose you're saving a User data. You'd just pass a User object to the method:
public function myfunc (User $user)
// map fields to the User signature.
}
This would be acceptable if you're in control of the User class since you'd have to change it to reflect model changes.
Use an ORM to handle this for you. You'd only have to update the xml specifications of the schema after you decide to change the database model, all necessary changes would be propagated to the application automatically. Of course the objects definition would change but that is inevitable.

Using a function in php - what am I doing wrong?

$users = [
"Andrew",
"Max",
"Larry",
"Ricardo",
"Lucy",
"Marcus",
"Sophie"
];
$sector_rel = [];
$location_rel = [];
function sectorRel($user){
return sector_rel[] = round(1/rand(1,10),3);
}
function locationRel($user){
return $location_rel[] = round(1/rand(1,20),3);
}
foreach($users as $user){
sectorRel($user);
locationRel($user);
}
This:
function sectorRel($user){
return sector_rel[] = round(1/rand(1,10),3);
}
Should be/could be:
function sectorRel($user){
global sector_rel;
sector_rel[] = round(1/rand(1,10),3);
}
The problem is that the functions don't have access to the array variables. You can import them into the function scope using the keyword global, if they are indeed global variables. Now, having global variables isn't a good thing, and for a small test it's okay, but eventually you'll be eliminating your globals and this solution won't work.
But alternatively, you could pass the array variables to the function as an argument. However, this still introduces a lot of logic in the function. The function has to be told about the array, it must know that it needs to add a value to the end, and it also needs to calculate the actual value to add.
So better, make the function just return the calculated value and add it to the array outside of the function:
function sectorRel($user){
// Assuming your are going to use 'user' here somewhere?
return round(1/rand(1,10),3);
}
function locationRel($user){
return round(1/rand(1,20),3);
}
foreach($users as $user){
sector_rel[] = sectorRel($user);
$location_rel[] = locationRel($user);
}
You can then wrap this entire snippet of code into another function and call that to populate the arrays. That way, you've quite reasonably split the responsibilities of the functions and have a piece of code that looks nice and clean.
You do not need to use return in either of sectorRel or locationRel. At the moment this will return the reference to that array and it is not being stored in a variable. You would need to store them in a variable or just get rid of the return. My PHP is a little weak at the moment but you should probably append the values in those functions to the array.
Also if you have a parameter called $user for each of those functions you should either use that parameter or just get rid of it.

How can I make an array of type "class" in PHP?

I have the following class with several properties and a method in PHP (This is simplified code).
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this[$i]->$Name = I find the name using RegExp and return the value to be stored here;
$this[$i]->Family = I find the family using RegExp and return the value to be stored here;
}
}//function
}//class
In the function Fetch_Name(), I want to find all the names and families that is in a text file using RegExp and store them as properties of object in the form of an array. But I don't know how should I define an array of the Member. Is it logical or I should define StdClass or 2-dimension array instead of class?
I found slightly similar discussion here, but a 2 dimensional array is used instead of storing data in the object using class properties.
I think my problem is in defining the following lines of code.
$Member = new Member();
$Member->Fetch_name();
The member that I have defined is not an array. If I do define it array, still it does not work. I did this
$Member[]= new Member();
But it gives error
Fatal error: Call to a member function Fetch_name() on a non-object in
if I give $Member[0]= new Member() then I don't know how to make $Member1 or Member[2] or so forth in the Fetch_Name function. I hope my question is not complex and illogical.
Many thanks in advance
A Member object represents one member. You're trying to overload it to represent or handle many members, which doesn't really make sense. In the end you'll want to end up with an array that holds many Member instances, not the other way around:
$members = array();
for (...) {
$members[] = new Member($name, $family);
}
Most likely you don't really need your Member class to do anything really; the extraction logic should reside outside of the Member class, perhaps in an Extractor class or something similar. From the outside, your code should likely look like this:
$parser = new TextFileParser('my_file.txt');
$members = $parser->extractMembers();
I think you should have two classes :
The first one, Fetcher (or call it as you like), with your function.
The second one, Member, with the properties Name and Family.
It is not the job of a Member to fetch in your text, that's why I would make another class.
In your function, do your job, and in the loop, do this :
for($i = 0; $i < 10; ++$i){
$member = new Member();
$member->setName($name);
$member->setFamily($family);
// The following is an example, do what you want with the generated Member
$this->members[$i] = $member;
}
The problem here is that you are not using the object of type Member as array correctly. The correct format of your code would be:
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this->Name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->Family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
First, $this->Name not $this->$Name because Name is already declared as a member variable and $this->Name[$i] is the correct syntax because $this reference to the current object, it cannot be converted to array, as itself. The array must be contained in the member variable.
L.E: I might add that You are not writing your code according to PHP naming standards. This does not affect your functionality, but it is good practice to write your code in the standard way. After all, there is a purpose of having a standard.
Here you have a guide on how to do that.
And I would write your code like this:
class Member{
public $name;
public $family;
public function fetchName(){
for($i=0;$i<10;$i++){
$this->name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
L.E2: Seeing what you comented above, I will modify my answer like this:
So you are saying that you have an object of which values must be stored into an array, after the call. Well, after is the key word here:
Initialize your object var:
$member = new Memeber();
$memebr->fechNames();
Initialize and array in foreach
$Member = new Member();
foreach ($Member->Name as $member_name){
$array['names'][] = $member_name;
}
foreach ($Member->Family as $member_family) {
$array['family'][] = $member_family;
}
var_dump($array);
Is this more of what you wanted?
Hope it helps!
Keep on coding!
Ares.

Passing $db object to other classes so they can access the database

I've got a PHP database class which connects to MySQL and wraps up all the PDO code and I use it to query the database. Basically in the page controller I make a new object:
$db = new Database($dbConfig);
Then I can get data from the database like so using a prepared query:
$params = array('username' => $username);
$result = $db->preparedSelect('select password, salt from users where username = :username', $params);
Which copies the PDO statement results into a new assoc array and returns just the database results back to the calling page. I iterate through them with a simple foreach like so:
foreach ($result as $key => $val)
{
$password = $val['password'];
$salt = $val['salt'];
}
Ok so lets say I want another class to use my $db object so it can access the database in some of the methods. At the moment the other class looks like this:
class General
{
// Database object
private $db;
public function __construct($db)
{
$this->db = $db;
}
}
That works well but I'm just wondering if the constructor should look like this:
public function __construct(&$db)
{
$this->db = $db;
}
That should mean I'm passing it in via reference and not copying the object into the other class. I don't want a copy of the $db object inside the class, I want it to use the existing database object so I don't have multiple copies of it floating around using up memory.
Is there any difference in PHP5 between passing it in as $db or &$db? From doing some reading, PHP5 by default passes objects by reference, and other people saying it now does it the Java way and some say using the & makes a hard link whatever that is. I'm confused. What's the best way to do it?
Many thanks!
There is a difference, but it's not really the difference you may think.
In PHP5, "$db" holding an object is basically equivalent to a "Foo *" in C or C++. In other words, $db doesn't store the whole object, it just stores a small token that lets the code find the object when necessary. When you pass this token by value, it's as fast as passing an integer value rather than a copy of the entire object. But if you assign $db, it doesn't change the value in the caller because you're changing your local variable holding the token to contain a different token.
If the function takes "&$db", that's basically the equivalent of passing "Foo **" in C, or more correctly a function taking a "Foo *&" in C++. The call is just as fast since it's the same size thing that's being passed, but inside the function if you assign to $db it will change the value of $db in the caller because the "pass by reference" variable points you to the memory location holding the token in the caller.
The best way to do it is to pass by value (do not use "&") unless you know what you're doing and why you're doing it.
That's a good question.
You can always do a test by opening a $db handle, passing it to a function, and checking them via the === operator to make sure they are the same object.
This would be a good job for static methods. That is how many frameworks accomplish the same task.
class DB
{
private static $db = FALSE:
public static function init($dbConfig)
{
if(! self:$db)
{
self::$db = new Database($dbConfig);
}
}
public static function preparedSelect($sql, $params)
{
if(! self::$db)
{
die("call the init method first");
}
// db stuff, where you would call $this->db call self::$db
}
}
So in your other classes where you want to make calls to the database all you would have to do is:
class General
{
public function __construct()
{
DB::init($dbConfig);
}
public function someMethod()
{
$params = array('username' => $username);
$result = DB::preparedSelect('select password, salt from users where username = :username', $params);
}
}

Categories