I'm building an object-oriented wrapper around curl and have created a setter for the CURLOPT_ constants that stores to a $property => $value array.
public function setCurlOpt($optCode, $optValue) {
$ch = $this->ch;
curl_setopt($ch, $optCode, $optValue);
$this->curlOpts[$optCode] = $optValue;
}
$curler->setCurlOpt(CURLOPT_FOLLOWLOCATION, 1);`
However, $optCode is not a valid index for the array, since it references a resource ID instead of the name of the constant.
In order to make this work, I need to be able to get the name of the constant. Is there a way to do something along the lines of this in PHP:
function getConstantName($fromVariable) {
... return $constantName;
}
$x = CONSTANT_Y;
echo getConstantName($x);
Output: CONSTANT_Y
Once constant is assigned to variable there no way to find out which constant was used in assignment. PHP just copies constant value into variable.
Only viable option for you is to use combination of defined() and constant() and pass only option name after CURLOPT_
public function setCurlOpt($optCode, $optValue) {
if (defined("CURLOPT_" . $optCode) === true)
{
$ch = $this->ch;
curl_setopt($ch, constant("CURLOPT_" . $optCode), $optValue);
$this->curlOpts[constant("CURLOPT_" . $optCode)] = $optValue;
}
}
$curler->setCurlOpt("FOLLOWLOCATION", 1);
This is kind of a long shot, but it might be worth a try:
function getConstantName($fromVariable) {
return array_search($fromVariable, get_defined_constants(), 1);
}
Related
I want to pass the variable in a function but get an error :
Working Example :
$text_line1 = function (TextToImage $handler) {
$line_first ="Vasim";
$handler->add($line_first)
->position(250, 100)
->font(24, __DIR__ . '/Roboto-Black.ttf')
->color(0, 0, 0);
};
Not Working :
$line_second = $imageMeta[2];
$text_line2 = function (TextToImage $handler) {
$handler->add($line_second)
->position(250, 150)
->font(20, __DIR__ . '/Roboto-Black.ttf')
->color(0, 0, 0);
};
What you are looking for is the "USE" keyword (for anonymous functions, as you are using in your second example). This allows additional variables from the parent scope to be passed into the closure. Its usage can be a little tricky, see the official PHP anonymous function documentation for more information (specifically, see example #3).
$line_second = $imageMeta[2];
$text_line2 = function (TextToImage $handler) use ($line_second) {
$handler->add($line_second)
->position(250, 150)
->font(20, __DIR__ . '/Roboto-Black.ttf')
->color(0, 0, 0);
};
If it is a class then access the variable by adding this keyword. If a normal function and add global in front of it to access a global variable.
aI want to set up a generic wrapper class method for setting options in curl requests, like so;
curl_setopt($curl_handles[$i], CURLOPT_RETURNTRANSFER, true);
However, I want to be able to pass the constant via the parameter in my method, so something like;
protected function set_option($i, $OPTION)
{
curl_setopt($curl_handles[$i], $OPTION, true);
}
Is this even possible? I haven't tried this, but I get the feeling this won't work. Can a name of constant be stored in a variable like this?
Are you asking how to pass a constant into a method parameter? What you have should work just fine.
protected function set_option($i, $OPTION)
{
curl_setopt($curl_handles[$i], $OPTION, true);
}
set_option(1, CURLOPT_RETURNTRANSFER);
The title may not make sense, not sure how to word it. Anyways, i'm practicing curl and OOP at the same time here with the riot games API. the API is kind of set up dumb where some info you want to request requires input that you wouldn't know off hand, so it requires another separate call to get the required info first.
class league
{
const URL = 'http://prod.api.pvp.net/api/lol/na/v1.1/';
const URL_2 = 'http://prod.api.pvp.net/api/lol/na/v2.1/';
const KEY = 'key';
public function summonerByName($summoner_name)
{
$request = 'summoner/by-name/' . $summoner_name . '?api_key =' . self::KEY;
return $this->fetch($request);
}
public function recentGamesByName($summoner_name)
{
//need to make two calls for this since you cant get recent games by name in the api
$id = summonerByName($summoner_name);
//now get recent games
$request = 'game/by-summoner/' . $id->id . '/recent';
return $this->fetch($request);
}
private function fetch($request)
{
$url = self::URL . $request . '?api_key=' . self::KEY;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
curl_close($curl);
return json_decode($data);
}
}
this is returning Fatal error: Call to undefined function summonerbyname()
if i use all this extra code below in the public function recentGamesByName() instead of $id = summonerByName() it works fine, but it seems unnecessary, and i want to replace that with just the function.
$grg = self::URL . 'summoner/by-name/' . $summoner_name . '?api_key=' . self::KEY;
$placeholder = curl_init($grg);
curl_setopt($placeholder, CURLOPT_RETURNTRANSFER, 1);
$ph_result = curl_exec($placeholder);
curl_close($placeholder);
$ph_result = json_decode($ph_result);
$id = $this->summonerByName($summoner_name);
You may want to read up on OOP.
A couple of things to remember about OOP. When you're INSIDE the class and need to call another function, you use the the special $this variable.
So you would use:
$someVariable = $this->summonerByName($summoner_name);
to get the results from that function.
If you're OUTSIDE the class and need to access that function, then you need to assign the entire class to a variable like so:
$league = new league();
and then you can access any function within the class using that variable.
So you could do...
$someVariable = $league->summonerByName($summoner_name);
if you had already assigned the class to a variable name $league. By the way, that $league variable? It's called an object. Thus Object Oriented Programming. Objects are kinda like arrays, but use a different syntax. You can print_r an object just like you can print_r an array. When accessing an object's variable you use the $objectName->variableName syntax instead of $arrayName['variablename'] syntax that you use in arrays.
function parts($part) {
$structure = 'http://' . $site_url . 'content/';
echo($tructure . $part . '.php');
}
This function uses a variable $site_url that was defined at the top of this page, but this variable is not being passed into the function.
How do we get it to return in the function?
Add second parameter
You need to pass additional parameter to your function:
function parts($site_url, $part) {
$structure = 'http://' . $site_url . 'content/';
echo $structure . $part . '.php';
}
In case of closures
If you'd rather use closures then you can import variable to the current scope (the use keyword):
$parts = function($part) use ($site_url) {
$structure = 'http://' . $site_url . 'content/';
echo $structure . $part . '.php';
};
global - a bad practice
This post is frequently read, so something needs to be clarified about global. Using it is considered a bad practice (refer to this and this).
For the completeness sake here is the solution using global:
function parts($part) {
global $site_url;
$structure = 'http://' . $site_url . 'content/';
echo($structure . $part . '.php');
}
It works because you have to tell interpreter that you want to use a global variable, now it thinks it's a local variable (within your function).
Suggested reading:
Variable scope in PHP
Anonymous functions
Alternatively, you can bring variables in from the outside scope by using closures with the use keyword.
$myVar = "foo";
$myFunction = function($arg1, $arg2) use ($myVar)
{
return $arg1 . $myVar . $arg2;
};
Do not forget that you also can pass these use variables by reference.
The use cases are when you need to change the use'd variable from inside of your callback (e.g. produce the new array of different objects from some source array of objects).
$sourcearray = [ (object) ['a' => 1], (object) ['a' => 2]];
$newarray = [];
array_walk($sourcearray, function ($item) use (&$newarray) {
$newarray[] = (object) ['times2' => $item->a * 2];
});
var_dump($newarray);
Now $newarray will comprise (pseudocode here for brevity) [{times2:2},{times2:4}].
On the contrary, using $newarray with no & modifier would make outer $newarray variable be read-only accessible from within the closure scope. But $newarray within closure scope would be a completelly different newly created variable living only within the closure scope.
Despite both variables' names are the same these would be two different variables. The outer $newarray variable would comprise [] in this case after the code has finishes.
NB: Do not forget that you would better use the immutable data structures (unlike the above) in your common web project. That would account for 99% of the use cases. So the approach above, using mutabliity, is for very seldom kind of "low level" use cases.
I suppose this depends on your architecture and whatever else you may need to consider, but you could also take the object-oriented approach and use a class.
class ClassName {
private $site_url;
function __construct( $url ) {
$this->site_url = $url;
}
public function parts( string $part ) {
echo 'http://' . $this->site_url . 'content/' . $part . '.php';
}
# You could build a bunch of other things here
# too and still have access to $this->site_url.
}
Then you can create and use the object wherever you'd like.
$obj = new ClassName($site_url);
$obj->parts('part_argument');
This could be overkill for what OP was specifically trying to achieve, but it's at least an option I wanted to put on the table for newcomers since nobody mentioned it yet.
The advantage here is scalability and containment. For example, if you find yourself needing to pass the same variables as references to multiple functions for the sake of a common task, that could be an indicator that a class is in order.
I had similar question. Answer: use global. And there are other options.
But if you need named function with usage of outside scope, here what I have:
global $myNamedFunctionWidelyAccessibleCallableWithScope;
$myNamedFunctionWidelyAccessibleCallableWithScope =
function ($argument) use ($part, $orWhatYouWant) {
echo($argument . $part . '.php');
// do something here
return $orWhatYouWant;
};
function myNamedFunctionWidelyAccessible(string $argument)
{
global $myNamedFunctionWidelyAccessibleCallableWithScope;
return $myNamedFunctionWidelyAccessibleCallableWithScope($argument);
}
It is useful for making function myNamedFunctionWidelyAccessible accissible from everywhere, but also binds it with scope. And I deliberately gave very long name, global things are evil :(
Here is documentation with a good example
You can add the below structure
$var1=5;
function sample() use ($var1){echo $var1;}
Just put in the function using GLOBAL keyword:
global $site_url;
I am trying to assign a variable to a class in PHP, however I am not getting any results?
Can anyone offer any assistance? The code is provided below. I am trying to echo the URL as shown below, by first assigning it to a class variable.
class PageClass {
var $absolute_path = NULL;
function get_absolute_path(){
$url = $this->absolute_path;
echo $url;
}
}
$page = new PageClass();
$page->absolute_path = "http://localhost:8888/smile2/organic/";
$page->get_absolute_path(); //this should echo the URL as defined above - but does not
It also works for me.
Take a look at a live example of your code here.
However, there are a few things you should change about your class.
First, Garvey does make a good point that you should not be using var. That's the older PHP4, less OOP conscious version. Rather declare each variable public or private. In fact, you should declare each function public or private too.
Generally, most classes have private variables, since you usually only want to change the variables in specific ways. To achieve this control you usually set several public methods to allow client functions to interact with your class only in restricted predetermined ways.
If you have a getter, you'd probably want a setter, since these are usually used with private variables, like I described above.
A final note is that functions named get usually return a value. If you want to display a value, it is customary to use a name like display_path or show_path:
<?php
class PageClass
{
private $absolute_path = NULL;
public function set_absolute_path($path)
{
$this->absolute_path = $path;
}
public function display_absolute_path()
{
echo $this->absolute_path;
}
}
$page = new PageClass();
$page->set_absolute_path("http://localhost:8888/smile2/organic/");
$page->display_absolute_path();
// The above outputs: http://localhost:8888/smile2/organic/
// Your variable is now safe from meddling.
// This:
// echo $this->absolute_path;
// Will not work. It will create an error like:
// Fatal error: Cannot access private property PageClass::$absolute_path on ...
?>
Live Example Here
There's a section on classes and objects in the online PHP reference.
class PageClass {
public $absolute_path = NULL;
function get_absolute_path(){
$url = $this->absolute_path;
return $url;
}
}
$page = new PageClass();
$page->absolute_path = "http://localhost:8888/smile2/organic/";
echo $page->get_absolute_path();
Works fine for me.
Have you checked that the script and esp. the code in question is executed at all?
E.g. add some unconditional debug-output to the script. Or install a debugger like XDebug to step through the code and inspect variables.
<?php
class PageClass {
var $absolute_path = NULL; // old php4 declaration, see http://docs.php.net/oop5
function get_absolute_path() { // again old php4 declaration
$url = $this->absolute_path;
echo "debug: "; var_dump($url);
echo $url;
}
}
$page = new PageClass();
$page->absolute_path = "http://localhost:8888/smile2/organic/";
echo "debug: page->get_absolute_path\n";
$page->get_absolute_path();