I am using https://github.com/seaofclouds/tweet
I want to pass index.php?consumer_key=xxx.
After passing this I want to get in the PHP class but i am getting error.
Here is the Code below. Full Code: http://pastebin.com/gCzxrhu4
//$consumer_key = $_GET['consumer_key'];
class ezTweet {
private $consumer_key = $consumer_key; // getting error
private $consumer_key = 'xxxxx'; // working
private $consumer_secret = 'xxxx';
//other things
}
Please Help.
A class is a stand-alone, re-usable and portable unit of code.
Therefore, it should never, ever, under any circumstances, rely on GLOBAL variables to initialize its properties or do its job.
If you need a class to have access to a value, pass that value to the class, either through the constructor or a setter method:
class EzTweet
{//class names start with UpperCase, and the { goes on the next line
private $consumer_key = null;//initialize to default, null
public function __construct($cKey = null)
{//pass value here, but default to null -> optional
$this->consumer_key = $cKey;//set value
}
public function setConsumerKey($cKey)
{
$this->consumer_key = $cKey;//set value later on through setter
return $this;
}
}
//use:
$ezTwitter = new EzTwitter();
if (isset($_GET['consumer_key']))
$ezTwitter->SetConsumerKey($_GET['consumer_key']);//set value
That's what I'd do, anyways. BTW: please check, and try to stick to, the coding standards.
Update:
It turns out you already have a constructor. Fine, just change it a bit to:
public function __construct($cKey = null)//add argument
{
$this->consumer_key = $cKey;//add this
// Initialize paths and etc.
$this->pathify($this->cache_dir);
$this->pathify($this->lib);
$this->message = '';
// Set server-side debug params
if ($this->debug === true)
error_reporting(-1);
else
error_reporting(0);
}
You can't set the property class value with a $variable, in this case you need before construct your class.
class ezTweet
{
private $consumer_key = '';
private $consumer_secret = 'xxxx';
public function __construct($consumer_key)
{
if (!is_string($consumer_key) || !strlen(trim($consumer_key))) {
throw new \InvalidArgumentException('"consumer_key" cannot be empty!');
}
$this->consumer_key = $consumer_key;
}
public function getConsumerKey()
{
return $this->consumer_key;
}
}
$consumer_key = (isset($_GET['consumer_key']) ? $_GET['consumer_key'] : null);
try {
$ezTweet = new ezTweet($consumer_key);
// [...]
}
catch (\InvalidArgumentException $InvalidArgumentException) {
echo $InvalidArgumentException->getMessage();
}
Related
I want to use a private method in a class called by public methods from the same class.
class Foo
{
private $updateAll = true;
private $updateA = false;
private $updateB = false;
public function updateA()
{
$this->updateAll = false;
$this->updateA = true;
$this->updateB = false;
$this->update();
}
public function updateB()
{
$this->updateAll = false;
$this->updateA = false;
$this->updateB = true;
$this->update();
}
private function update()
{
// Code here...
if ($this->updateAll) {
// set all api call params
}
if ($this->updateA) {
// set api call param
}
if ($this->updateB) {
// set api call param
}
// Code here...
}
}
Is this a proper use of class properties as arguments?
It works but I don't know whether there is a better way to do this. My purpose is to kinda use dynamic method arguments without the need to pass 3 arguments to update().
Your code is not wrong and should work just fine as you say, but it does feel a bit weird... I think any of the following approaches is cleaner and more flexible than your code. I'm sure there will be lots of other options perfectly valid, these are just some ideas...
Multiple method arguments
As it's been suggested to you in the comments, I think the normal way to do that is actually just adding the arguments to the update() method...
class Updater
{
public function update($all = true, $a = false, $b = false)
{
// Code...
}
}
One constant method argument
However, in your example, the options seem to be mutually exclusive (any combination of 2 options is redundant), so you can do perfectly fine with just one parameter!
class Updater
{
const UPDATE_ALL = 'all';
const UPDATE_A = 'a';
const UPDATE_B = 'b';
public function update($updateMode = self::UPDATE_ALL)
{
// Code...
}
}
Command pattern
If your example is not realistic, and you have a scenario with lots of options that are not mutually exclusive, I'd use something similar to a command pattern, where the class in charge to define the options of the operations is different from the class that performs the operation...
class Updater
{
public function update(UpdateCommand $command)
{
// Code...
}
}
class UpdateCommand
{
public $paramA = false;
public $paramB = false;
// ...
public $paramZ = false;
}
Fluent interface
Or you could also use a fluent interface. Although that's a bit harder to test...
class Updater
{
private $paramA = false;
private $paramB = false;
// ...
private $paramZ = false;
public function withA()
{
$this->paramA = true;
return $this;
}
public function withB()
{
$this->paramB = true;
return $this;
}
// ...
public function withZ()
{
$this->paramZ = true;
return $this;
}
public function run()
{
// Code...
}
}
I'm learning how to use classes properly... I'm looking at usercake and most of it makes sense, however I'm not sure what the __construct function is doing. I understand it gets called when you create the class... i.e. $loggedInUser = new loggedInUser();
What does the stuff below do and why do I need it?
function __construct($user, $display, $title, $pass, $email)
{
//Used for display only
$this->displayname = $display;
//Sanitize
$this->clean_email = sanitize($email);
$this->clean_password = trim($pass);
$this->username = sanitize($user);
$this->title = sanitize($title);
if(usernameExists($this->username))
{
$this->username_taken = true;
}
else if(displayNameExists($this->displayname))
{
$this->displayname_taken = true;
}
else if(emailExists($this->clean_email))
{
$this->email_taken = true;
}
else
{
//No problems have been found.
$this->status = true;
}
}
Edit: Here is how the class gets called:
$loggedInUser = new loggedInUser();
$loggedInUser->email = $userdetails["email"];
$loggedInUser->user_id = $userdetails["id"];
$loggedInUser->hash_pw = $userdetails["password"];
$loggedInUser->title = $userdetails["title"];
$loggedInUser->displayname = $userdetails["display_name"];
$loggedInUser->username = $userdetails["user_name"];
$loggedInUser->alerts = array();
It is the constructor function. When you create an instance of that class your constructor function is run.
For example, with your constructor (I don't know your class name).
$class = new MyClass("jdoe", "John Doe", "Standard User", "Passw0rd!","jdoe#example.com");`
This will create a new MyClass and store it in $class.
As for its purpose, it lets you initialize the object to a starting state of some kind. You can populate properties, set default values, or just do nothing. It is really application specific.
EDIT (in response to OP's edit)
I would really suggest keeping your object properties either protected or private and use setter/getters to access that data. You are giving public access to your objects properties, which isn't bad, but it can lead to accidentally changing something you didn't mean to change. Maybe you should consider something like this:
<?php
class LoggedInUser
{
private $id;
private $username;
private $password;
private $displayname;
private $email;
private $title;
public function __construct($id, $username, $password, $displayname, $email, $title)
{
$this->setID($id);
$this->setUsername($username);
$this->setPassword($password);
$this->setDisplayName($displayname);
$this->setEmail($email);
$this->title($title);
}
public function sanitize($var)
{
//Sanitize $var and then...
return $var;
}
public function setID($num)
{
$this->id = $this->sanitize($num);
}
public function setUsername($string)
{
$this->username = $this->sanitize($string);
}
//Keep adding other "set" methods.
}
?>
Then to use this you would do something like:
$loggedin = new LoggedInUser( "arg1", "arg2", "etc..." );
Now your object is setup with the starting state. If you need to change a property later you can always do:
$loggedin->setTitle("Correct Title");
Make sure you create functions to return your properties as well. In the example above your properties are private so a call to $loggedin->title would generate an error in PHP
// Set construct function which will run when your class is called
function __construct($user, $display, $title, $pass, $email)
{
// Sets display name
$this->displayname = $display;
// Sanitizing user inputted data (See SQL injection/XSS attacks)
$this->clean_email = sanitize($email);
$this->clean_password = trim($pass);
$this->username = sanitize($user);
$this->title = sanitize($title);
// Check if any duplicates of the user inputted data exist already in the database
// If any of these checks return true, the status wont be set to true, and further code wont be ran
if(usernameExists($this->username))
{
$this->username_taken = true;
}
else if(displayNameExists($this->displayname))
{
$this->displayname_taken = true;
}
else if(emailExists($this->clean_email))
{
$this->email_taken = true;
}
else
{
// No duplicate information has been found, set status and continue registration
$this->status = true;
}
}
You need it because initialize the object you create.
Probably a newbie question, but then I'm learning on the fly:
Within the following code, I need to name $targetname and $imagelocation come from the $_POST variable coming in... I KNOW I can't define these variables properly the way I'm trying to, but am a bit stumped... help anyone?
class PostNewTarget{
//Server Keys
private $access_key = "123456";
private $secret_key = "142356";
private $targetName = $_POST['the_target'];
private $imageLocation = $_POST['the_image'];
function PostNewTarget(){
$this->jsonRequestObject = json_encode( array( 'width'=>300, 'name'=>$this->targetName , 'image'=>$this->getImageAsBase64() , 'application_metadata'=>base64_encode($_POST['myfile']) , 'active_flag'=>1 ) );
$this->execPostNewTarget();
}
...
Pass into the method:
function PostNewTarget($targetName, $imageLocation)
Then call with:
PostNewTarget($_POST['the_target'], $_POST['the_image'])
You could possibly add in the constructor, but I wouldn't:
public function __construct() {
$this->targetName = $_POST['the_target'];
$this->imageLocation = $_POST['the_image'];
}
You need to initialize first your class properties
You can set $_POST values to your class properties when you create your class object using constructor, or you can set just when you need to get these values, I made it in your example
class PostNewTarget{
//Server Keys
private $access_key = "123456";
private $secret_key = "142356";
private $targetName = "";
private $imageLocation = "";
//you can give class variables values in the constructor
//so it'll be setted right when object creation
function __construct($n){
$this->targetName = $_POST['the_target'];
$this->imageLocation = $_POST['the_image'];
}
function PostNewTarget(){
//or you set just only when you need values
$this->targetName = $_POST['the_target'];
$this->imageLocation = $_POST['the_image'];
$this->jsonRequestObject = json_encode( array( 'width'=>300, 'name'=>$this->targetName , 'image'=>$this->getImageAsBase64() , 'application_metadata'=>base64_encode($_POST['myfile']) , 'active_flag'=>1 ) );
$this->execPostNewTarget();
}
}
Treat it as a normal variable and put it in a constructor or mutator or argument of a function if it's only needed in that function. Here is an example using a constructor, but the logic is the same in every case.
class Example {
public $varFromPOST;
public $name
public function __construct($var, $name) {
$this->varFromPOST = $var
$this->name = $name
}
}
Then in your index.php:
$_POST['foo'] = 100;
$userName = 'Bob';
$Example = new Example($_POST['foo'], $userName);
Seems straightforward, if I didn't misunderstand your question.
class Assignation {
private $VVal_1 = 1;
private $VNam_1 = "One";
//....Multiple Items
private $VVal_2000 = 2000; //For Example
private $VNam_2000 = "Two Thousands"; //For Example
private static $Hash = array(); //How to initialize???
private static function Assigning(){
//This function for to assign the array elements (initialize)
global $Hash;
$this->Hash = array(); //to empty Hash variable and not add more data than it should.
$this->Hash[$this->VVal_1] = $this->VNam_1;
//....Multiple Items
$this->Hash[$this->VVal_2000] = $this->VNam_2000;
}
public static function GetVal($Nam) {
$this->Assigning(); //or use self::Assigning(); //I want to avoid this call
if (array_search($Nam, $this->Hash))
return array_search($Nam, $this->Hash);
return -1;//error
}
public static function GetNam($Val) {
$this->Assigning(); //or use self::Assigning(); //I want to avoid this call
if (array_key_exists($Val, $this->Hash))
return $this->Hash[$Val];
return "Error";
}
}
Class Testing {
static $OtherVal = Assignation::GetVal("BLABLA"); //for example
static $OtherNam = Assignation::GetNam(20); //for example
//Other functions...
}
Hi, you can see my script or code php...
I need to initialize the Hash array, this have static word because I need to use it in other static function. And this "other function" need to use it for other static variable...
I need to know how to implement it the right way..
Thanks chep.-.
<?php
echo "pre-Class Assignation<br/>";
class Assignation {
private $VVal_1 = 1;
private $VNam_1 = "One";
private $VVal_2K = 2000;
private $VNam_2K = "Two Thousands";
private static $Hash = array();
private static function Assigning(){
if(!empty(self::$Hash)) return;
self::$Hash[$this->VVal_1] = $this->VNam_1;
self::$Hash[$this->VVal_2K] = $this->VNam_2K;
}
public static function GetVal($Nam) {
self::Assigning();
if (array_search($Nam, self::$Hash)) return array_search($Nam, self::$Hash);
return -1;//error
}
public static function GetNam($Val) {
self::Assigning();
if (array_key_exists($Val, self::$Hash)) return self::$Hash[$Val];
return "Error";
}
}
echo "post-Class Testing<br/>";
echo Assignation::GetVal("BLABLA");
echo "post-Class Mid<br/>";
echo Assignation::GetNam(20);
echo "post-Class Sample<br/>";
//Testing::MyPrint();
?>
This code is not running, somebody help me testing the code...
result:
pre-Class Assignation
post-Class Assignation
post-Class Testing
that mean:
" echo Assignation::GetVal("BLABLA");"
have error...
In Assigning(), try using self::$Hash rather than $this->Hash and remove the global $Hash. Same applies for calling Assigning(): self::Assigning() as your comments suggest.
$this references the current object, so you must use self:: for all static functions and member data when inside the class.
Also, if this is your real code and not just a sample, you may want to check whether you have already done initialization, otherwise you will be doing it for every call to GetVal() and GetNam(). You could do this by adding something like if(!empty(self::$Hash)) return at the beginning of Assigning()
EDIT
private static function Assigning() {
if(!empty(self::$Hash)) return; // already populated
self::$Hash = array();
self::$Hash[$this->VVal_1] = $this->VNam_1;
//....Multiple Items
self::$Hash[$this->VVal_2K] = $this->VNam_2K;
}
Hi in my user class i am passing the variables in constructor instead of passing variables i want to pass as an array.
Class User{
var $userid;
var $alias;
var $firstname;
var $password;
var $email;
var $photo;
var $avatar_url;
var $thumb;
var $crop_url;
var $crop_position;
protected $db;
function User($userid='',$alias='',$firstname='',$lastname='',$password='',$email='',$photo='',$avatar_url='',$thumb='',$crop_url='',$crop_position='',PDO $db){
$this->userid=$userid;
$this->alias= $alias;
$this->firstname=$firstname;
$this->lastname=$lastname;
$this->password= $password;
$this->email=$email;
$this->photo= $photo;
$this->avatar_url= $avatar_url;
$this->thumb= $thumb;
$this->crop_url= $crop_url;
$this->crop_position= $crop_position;
$this->db = $db;
}
}
and the variable coming in constructor
$user=new User($id,$alias,$firstname,$lastname,$password,$email,$photo='',$avatar_url='',$thumb='',$crop_url='',$crop_position='',$db);
this all are coming through the request variable.
Please help.Thanks
You didn't clarify what your issue is. If you want to pass an array, then pass an array. If you cannot change your API for the ctor for BC reasons, you can add another method to your User class, e.g.
class User
{
// other code …
public function populateFromArray(array $data)
{
foreach ($data as $property => $value) {
if (property_exists($this, $property)) {
$user->$property = $value;
}
}
}
}
Then you can do
$user = new User('','','','','','','','','','','',$db);
$user->populateFromArray(array(
'id' => 'johndoe',
'email' => 'jdoe#example.com',
// other …
));
The ctor call looks pretty ugly, so if you can afford to change the API, I suggest to move required arguments to the beginning of the signature. This is suggested good practise in the PHP Manual anyway, e.g. change your ctor to
public function __construct(PDO $pdo, $id = '', $email = '', …) {
Note that I changed it to the new PHP5 style constructor. Naming the ctor after the class name is PHP4 style and is not compatible with namespaces as of PHP5.3.3.. You might also want to change your var keyword to public (or better yet protected and add proper getter and setter).
Since everything but the PDO instance is optional, you can just as well remove all the optional arguments and always use your new populateFromArray method instead, reducing the instantiation to
$user = new User($db);
$user->populateFromArray($dataArray);
If you want to implement the populateFromArray functionality in other classes as well, you might want to consider adding an interface IPopulate, e.g.
interface IPopulate
{
public function populateFromArray(array $data);
}
But your classes implementing this interface would have to add the method body each time, which is a bit redundant given that our populating code is quite generic. With php.next there will be traits for an elegant solution for horizontal reuse like this.
Yet another possible solution would be to just use the Reflection API to pass the array to your regular ctor (though you should give it a benchmark afterwards because the Reflection API is considered slow). See
Pass arguments from array in php to constructor
User.php Class:
// define your default values here. so that you will not have to pass them
// everytime when you pass the array to `AssignVal` function.
Class User{
var $userid = '';
var $alias = '';
var $firstname = '';
var $password = '';
var $email = '';
var $photo = '';
var $avatar_url = '';
var $thumb = '';
var $crop_url = '';
var $crop_position = '';
protected $db;
function User(PDO $db) {
$this->db = $db;
}
}
Index.php (where you want the object to be created):
$user = assignVal('User',$arr);
functions.php (a place where you include all your functions):
// the following function creates an object with the array you send it.
// this is specially useful if your class contains a lot of variables
// thus minimizing the manual work of defining constructors again and again...
function assignVal($obj,$arr,$child=null) {
if (is_string($obj)) $obj = new $obj();
$applyon = $child == null ? $obj : $obj->$child;
if(!empty($arr)) {
foreach ($arr as $name => $val) {
$applyon->$name = $val;
}
}
if ($child != null) $obj->$child = $applyon;
else $obj = $applyon;
return $obj;
}
First create your array:
$Usr_info = array('id' => 0, 'alias' => 'value'); //add all the values you want like that
And then in your constructor you can access each item in the array:
function User($Usr_info)
{
$this->userid = $Usr_info['id'];
//and so on...
}
version for PHP5
class User {
private $userid;
...
public function assign ($class_member, $value) {
$this->$class_member = $value;
}
public function __construct ($db) {
$this->db = $db;
}
}
...
$user = new User($db);
$user->assign('userid', 1);