passing variable to a php class - php

I am a beginner in php. and trying to work with Oauth. but this is not the point. the point is following: I have an Oauth class, there are four functions which return urls like this:
class tOauth{
......
function accessTokenURL() {
return 'http://api.twitter.com/oauth/access_token';
}
function authenticateURL() {
return 'http://api.twitter.com/oauth/authenticate';
}
......
}
this works fine. but now I want these functions to be generic, such that they are suitable for any social sites. this means I have to danymically pass all urls and return them at run time. so I come up something like this:
class tOauth{
....
public $accessTokenURL,$authenticateURL;
function accessTokenURL() {
return $this->accessTokenURL;
}
function authenticateURL() {
return $this->authenticateURL;
}
....
}
and at run time I call them like this:
$oauth=new Oauth(key,secret);
$oauth->accessTokenURL='http://www.facebook.com/oauth/access_token';
$oauth->authenticateURL='http://www.facebook.com/oauth/authenticate';
$token=$oauth->requestToken($someurl);
but for some reason, this doesn't seems to work. I did not change anything else. it seems I can not daynamically assign variables like this. does any body know what may be the problem? thanks for any tips.
Update: whole sample code can be find here: https://github.com/abraham/twitteroauth/blob/master/twitteroauth/twitteroauth.php

Why not write getter and setter methods for your class variables?
You already have methods, that return accessTokenURL and authentificateURL.
I believe this might work:
class tOauth{
....
public $accessTokenURL,$authenticateURL;
function accessTokenURL() {
return $this->accessTokenURL;
}
function authenticateURL() {
return $this->authenticateURL;
}
function set_accessTokenURL($token)
{
$this->accessTokenURL = $token;
}
function set_authenticateTokenURL($token)
{
$this->authenticateTokenURL = $token;
}
....
}

Update: Your code does not show any details about requestToken() method. The following solution gets you access token instead.
You read something you did not set according to your code. Replace the last line with
$token=$oauth->accessToken($someurl);
and it will work for accessToken.
Also consider inheritance that will allow you to store common instructions in tOauth class and the service-specific ones in separate classes inheriting from it (eg. Twitter_Oauth may inherit from your tOauth class and have specific URLs set to default from the beginning, without the need to set them every time).

Related

Calling mulltiple methods of the same class

In my class Helper() I have 2 methods which look like this:
public function is_active_page($page) {
$url = explode("/",$_SERVER["REQUEST_URI"]);
if (end($url) === $page) {
return true;
}
}
public function go_to_dashboard() {
if (isset($_SESSION['login'])) {
header('Location: http://example.com');
}
}
I would now like to call them like this: $helper->is_active_page('page')->go_to_dashboard(); instead of using 2 lines for each method.
For some reason this is not working for me. Why?
In order to be able to chain methods, those methods need to return the original Helper instance. Try returning $this from inside the methods. Like RomanPerekhrest commented however, I dont think the methods you listed here are suitable for chaining. You would be better off with adding another method to your class that combines the two you stated here.
I'm not exactly sure what you are trying to do, but something along the lines of below might be what you are looking for:
public function redirect($page){
if($this->is_active_page($page)){
$this->go_to_dashboard();
}
}
Lastly, you could think about reducing the scope of your is_active_page and go_to_dashboard functions, if they no longer need to be called from outside the Helper class.

Use variable when calling class method

I can't seem to find an answer to this albeit I am probably not looking for the right thing being new to classes and oop. I would like to know if you can use a variable when calling a class method.
When a user logs into my system I wish to display them some chart on a dashboard based on their user role.
For starters here is an example of my class
class Dashboard
{
function get_guest_graph1()
{
return 'guest graph';
}
function get_user_graph1()
{
return 'user graph';
}
}
On the page I can echo say
$user->userRole;
This will return either guest or user.
So once I have established the role and put this into a varible ie
$role
Is there a way I can then do the following?
Dashboard::get_$role_graph1();
While this question was already answered, I think there are far better ways to handle this, if readability is in question.
For starters, use camel casing on functions rather than chaining_characters_for_variable_names.
class Dashboard {
function getFirstUserGraph() {
return 'user graph 1';
}
}
I would discourage using numbers in a function name!
Secondly, to accomplish your desire of calling Dashboard::getFirstUserGraph() simply make that a static function:
public static function getFirstUserGraph() {}
Then you don't have to instantiate the class but use it statically.
Lastly, to call a class method via a variable is rather simple without the ugliness of call_user_func(). See below:
$getGraph = "getFirstUserGraph";
Dashboard::$getGraph();
Works like a champ and looks a lot nicer. Hope that helps!
Yes, you can, but use with caution:
call_user_func(array("Dashboard", "get_" . $role . "_graph1"), $args);

PHPUnit mock/stub functionality within class

I need some advice on how I can proceed with this issue.
Using PHP
An example would be:
class BuilderClass {
function getClass($id, $some, $vars){
$dbResult = new db_Class::getDbRows($id, $some, $vars);
foreach(...)
// Build something from the database values
return self;
}
}
So what I want to do is to create a test case where I somehow mock the db results.
I have not found any great way to do this, please point me in the right direction or similar to get this working for me.
I could change something within the builder itself for example call a class that runs the function: FunctionRunner::runStaticFunction("db_Class", "getDbRows", $args, $something_else); But at the moment I don't know if that is possible neither. Any research articles that cover this or any sites that explain this. I'd appriciate anything at the moment.
Thanks
/Marcus
Split the operations of retrieving data from database, and building the data.
class BuilderClass {
function getClass($id, $some, $vars){
$dbResult = new db_Class::getDbRows($id, $some, $vars);
return doGetClass($dbResult);
}
function doGetClass($dbResult) {
foreach(...)
// Build something from the database values
return self;
}
}
That way, you can test doGetClass in isolation from calling the database .
As often the case, inability to easily write tests for your functions is caused by a flaw in your application design. In this case the db_Class is tightly coupled to your BuilderClass.
A proper solution would be to have a Database object in your BuilderClass using dependency injection, and mocking that injection to return a static result.
class BuilderClass
{
protected $oDatabase;
public function __construct(db_Class $oDatabase) {
$this->oDatabase = $oDataabse;
}
public function getClass($someVars) {
$this->oDatabase->getDbRows($someVars);
}
}
This way, the Database object is easily replaced with a stub.
There are many ways to do this, but since we are talking PHP, you could leverage the magic class loader function.
Simply put, if you want to mock the data access layer, you just create an object with the actual name of the data class, and the autoloader is never called.
Want to actually access the database? don't define the class and the autoloader will be called when something tries to access the database, which should then know what to do to load the class.
Mostly my autoloaders, when I use them, tend to look something like this;
function __autoload($className)
{
if(file_exists('../includes/'.$className.'.php'))
require_once('../includes/'.$className.'.php');
}

Any way to declare a regular function within a class as a method?

I have a scenario where I'm trying to incorporate several people's PHP work, some of it OOP and some not. I want to pull a library file of functions into a class and have those functions be available to other files that reference the class. I know I can just call the library functions directly, but then I would have to update all of the dependent files to do likewise. Example:
class do_something {
function test_state() {
...
}
if ($this->test_state($var)) {
...
}
}
Where test_state() is identical to the same-named function in the library file, making for redundant code to keep sync'd. That can be changed to:
class do_something {
if (test_state($var)) {
...
}
}
But that creates the aforementioned problem of $this->test_state() not being available to files dependent on the class. What I'd like to be able to do is something like:
class do_something {
public function test_state() = test_state();
if ($this->test_state($var)) {
...
}
}
Obviously, that's a very rough and incorrect example of what I'm trying to do... Is there any way in OOP to make that sort of reassignment, making the method of the same name as the function available within the class?
You can use a workaround to simulate this. In fact you would often want this approach to bolt on closures to objects in PHP. It leverages the magic __call method in PHP to redirect method calls to ordinary functions (beware: no $this available).
class do_something {
function __call($func, $args) {
if (isset($this->$func) && is_callable($this->$func)) {
return call_user_func_array($this->$func, $args);
}
}
}
Then you can "register" functions that you want to allow (or closures) with a simple assignment:
$do_something->function_name = "global_function_name";
$do_something->or_even = array("other_class", "method");
But again, this doesn't make them proper methods as such.
You'd create your base utility class, then extend it. See PHP's manual entry for inheritance for the details. I'm not saying this is the best solution for your exact situation, but I think it answers the question you were trying to get at.
What you're asking for isn't possible directly, but can be faked with a quick (horrible) hack:
class do_something {
public function test_state($param) {
return test_state($param);
}
...
$this->test_state($param);
...
}
Good luck with refactoring!

PHP OO Cancel Construction

This is actually an interesting question, and there's an easy (but ugly) fix to it (see below).
So I'm asking if there's a better way to do it.
What I'd like to do is making an object constructor return something else rather than a new instance.
Here's an example of what I'm trying to achieve:
$GLOBALS['object_cache']=array();
class Test {
public function __construct($id=0){
if(isset( $GLOBALS['object_cache'][$id] ))
return $GLOBALS['object_cache'][$id];
$GLOBALS['object_cache'][$id]=$this;
}
}
$t0=new Test(0);
$t1=new Test(1);
$t01=new Test(0);
// modifying $t01 would presumably also modify $t0
The easy (but ugly?) fix:
$GLOBALS['object_cache']=array();
class Test {
public static function create($id=0){
if(isset( $GLOBALS['object_cache'][$id] ))
return $GLOBALS['object_cache'][$id];
$new=new Test();
$GLOBALS['object_cache'][$id]=$new;
return $new;
}
}
$t0=Test::create(0);
$t1=Test::create(1);
$t01=Test::create(0);
// modifying $t01 would presumably also modify $t0
What do you guys think? Example 1 doesn't work, by the way; it returns a new instance regardless of the return statement.
So am I missing something, or is the better way the second one?
PS: No need stating the obvious about patterns (factory/singleton)...
Omg. Constructor cannot return anything.
It is called factory method pattern http://en.wikipedia.org/wiki/Factory_method_pattern and it is a common practice to instantiate objects.
ps: Store the instances in static class variable and second solution will not be so weird like now.
You could also use a procedural version:
class Test {
function __construct($i) {}
}
function Test($i) {
static $cache;
if (isset($cache[$i])) {
return $cache[$i];
}
else {
return $cache[$i] = new Test($i);
}
}
It's slightly nicer on the eyes, and allows for e.g. instant fluent Test(1)->do()->else() calls.
Basically what you're trying to do is implementing a Singleton pattern combined with a Factory method pattern. Anyone should be able to tell how it works if you document it in your technical documentation (and in your comments), so the first way can be used.
The second solution actually seems less obvious to me.

Categories