I have a Player class which has properties: $infantry, $vehicles and $air.
When battling players, I don't know which property is being used as an array which holds the properties to be used is shuffled to create a random order.
I try to use this, but it doesn't work. Strangely it doesn't give me empty property error so I assume it's pointing to some property:
<?php
$typeOrder = array(_INF_, _VEH_, _AIR_); // _INF_ const = "infantry" etc
$turnOrder = $typeOrder;
shuffle($turnOrder);
for($i = 0; $i < 3; $i++)
{
$attType = $turnOrder[$i];
print $p1->$attType;
}
?>
How do I properly access a property with the value held in a constant?
Thanks.
It should work - as long as $p1->infantry etc exist. What error does PHP give you exactly?
By the way, have a look at array_rand().
Related
I have 20 variables with name $encode1,$encode2....,$encode20.
Now, I want to print these variable in the for loop by combining $encode.$1 to achive variable $encode1.
Loop example:
for($i =1;$i<=20;$i++)
{
$echo = $encodedImage.$i; => What to do here?
}
How could I access the names by using iterator?
Plus, I don't want to create an array. I just want to access them directly dynamically.
I haven't found any answer on stackoverflow regarding this topic. If there is any, please share me the link. Thanks!
using variables variable to achieve such a approach
Sometimes it is convenient to be able to have variable variable names.
That is, a variable name which can be set and used dynamically. A
normal variable is set with a statement such as:
for($i = 1; $i <= 20; $i++) {
$myVariable = "encoded" . $i;
echo $$myVariable;
}
Use it this way.
Try this code snippet here
<?php
$encoded1=10;
$encoded2=20;
$encoded3=30;
for($i =1;$i<=3;$i++)
{
echo ${"encoded".$i};
}
I am playing around with PHP Calendar (Corey Worrell) and had a question regarding instance looping. In order to initialize the calendar, I have to output this:
$calendar->standard('today')
->standard('prev-next')
->standard('holidays')
->attach($event1)
->attach($event2)
->attach($event3)
->attach($event4)
->attach($event5)
->attach($event6)
->attach($event7)
->attach($event8)
->attach($event9)
->attach($event10)
->attach($event11)
->attach($event12)
->attach($event13)
->attach($event14)
->attach($event15)
->attach($event16)
->attach($event17);
Each ->attach($event#) outputs an event on the calendar. I want to loop through these numerically incrementing event names but adding a for loop anywhere in that code breaks everything, outputting this error:
PHP Catchable fatal error: Argument 1 passed to
Event_Subject::attach() must be an instance of Event_Observer, null
given, called in /calendar/index.php on line 75 and defined in
/calendar/classes/event_subject.php on line 21
Here is the loop I've tried:
$calendar->standard('today')
->standard('prev-next')
->standard('holidays')
for ($inc = 0; $inc <= $number_of_events; $inc++) {
if ($inc == $number_of_events) {
->attach($$event_name);
}
else {
->attach($$event_name)
}
}
How can I loop inside of here? My events are stored in MySQL and I am doing an $number_of_events = $result->num_rows to determine the number of events returned. The ->attach($event#) would loop, repeating until the total $number_of_events is hit.
That's called method chaining. Each method of the class returns an instance of the called object via $this, allowing you to stack method calls. Method chaining is possible because the function returns a reference to your object.
Because each function in the class that supports method chaining returns the calling object, you can just re-assign the returned object back into the original $calander variable;
for ($inc = 0; $inc <= $number_of_events; $inc++) {
if ($inc == $number_of_events) {
$calander = $calander->attach($event1);
}
else {
$calander = $calander->attach($event1);
}
}
Additionally, if you wanted to iterate through variable names, you could use a variable variable inside your loop;
$variable = "event".$inc;
$calander = $calander->attach($$variable);
So this would become $event0, $event1, $event2, etc.
The problem with the loop is that there is nothing in front of the -> operator. The -> references a property of an object, but you do not provide it with an object. You could solve it by putting $calendar in front of the lonesome operators ($calendar->...), but it would still not be very pretty code.
I suggest this instead:
I think you could just add the events one by one inside the loop I assume you are already using to create the $event1, $event2, etc. I don't know what you are using to get the data out of the database or what your table structure looks like, but I will provide an example for MySQLi. It should be easy to modify for other alternatives.
//Add the standards.
$calendar->standard('today')
->standard('prev-next')
->standard('holidays');
//Connect to the database here and query for the events using MySQLi.
//Loop through the results.
while($row = $result->fetch_assoc()) {
//Create an event from the database row...
$event = calendar->event()
->condition('timestamp', $row['TIMESTAMP'])
->title('Hello All', $row['TITLE'])
->output('My Custom Event', $row['OUTPUT']);
//...and attach it.
$calendar->attach($event);
}
This is not code to be copy-pasted directly, but more of a suggestion about how to organize it.
Also, for the future, you should not name variables $name1, $name2, etc and then use $$ to reference them. Use arrays instead.
Here's the solution. Not sure why changing this to reference $calendar each line worked, but it did. Thanks everyone.
$calendar->standard('today');
$calendar->standard('prev-next');
$calendar->standard('holidays');
for ($x = 1; $x <= $number_of_events; $x++) {
$event_name = "event".$x;
$calendar->attach($$event_name);
}
Is it possible in PHP to access a member of an object where the name of the member is specified by a class constant?
Consider this example:
class X{
const foo = "abc";
}
class Y{
public $abc;
}
$y = new Y();
$y->X::foo = 23; //This does not work
The parser doesn't accept the last line but this is what I want. I want to access the field with the name stored in the class constant X::foo. Is there a syntax to achieve that?
Use variable variables, either via a temp or directly:
$name = X::foo; // Via temp var
$y->$name = 23; // Access the member by the string's content
var_dump($y->{X::foo}); // Dumps 23
Working sample here.
You should write your code like this
$y->{X::foo} = 23;
Hope it helps
I have an object with lots of properties. Some of the properties have their names start with the same string of text (in my example to come "bullet"), followed by an integer.
I can fetch the property values as follows:
echo $objectName->bullet1;
echo $objectName->bullet2;
echo $objectName->bullet3;
and so on.
I'm trying to write a for loop to get the first 20 of these, and at the moment it looks a bit like:
for ($i = 1; $i <= 20; $i++){
if ($objectName->bullet$i){
echo $objectName->bullet$i;
}
}
But this isn't working. I know I could write something like
$bulletsArray[1] = $objectName->bullet1;
$bulletsArray[2] = $objectName->bullet2;
$bulletsArray[3] = $objectName->bullet3;
all the way through to 20, then put a for loop on that, but I'm sure there must be a cleaner way. Can someone point me in the right direction?
This is how you can do it:
for ($i = 1; $i <= 20; $i++){
$propertyName = "bullet$i";
if ($objectName->$propertyName){
echo $info->$propertyName;
}
}
Though I think using an array instead of the object would be a better solution.
$var = 'myVariable';
$value = $object->$var;
is the correct syntax for accessing a field by name in PHP.
In your case it would look something like this:
for ($i = 1; $i <= 20; $i++)
{
$var = 'bullet'.$i;
if ($objectName->$var)
{
echo $info->$var;
}
}
Both previous answers have the "try it, if it doesn't work, move on" and are working for a very specific situation. Let me give you a more generic approach, which, sadly, requires PHP 5.
A bit about Reflection
Reflection allows you to reflect on an object or class to extract useful information about it. In particular, you can use Reflection to get all the properties set in a class, whether static, at run-time, or generated on the go.
To do this, start by initiating your Reflection object (assuming your class object is $object) as follows:
$refObj = new ReflectionObject($object);
This will now give you a reflection interface. Notice the useful ReflectionObject::getProperties() method - it allows you to get all properties set in a class (and you can filter by public, protected, private etc... if needed). We'll use exactly this:
$yourNewArray = array();
$PropertyArray = $refObj->getProperties();
$pCount = count($PropertyArray);
for ($i = 0; $i < $pCount; $i++) {
$yourNewArray[$PropertyArray[$i]->getName()] = $PropertyArray[$i]->getValue($object);
}
Done. Completely generic, works anywhere.
in my system, which doesn't allow me to do
$myPropertyValue = $object->$property;
I still can get to the value of the 'variable' property name with the function below; you can set $property without php complaining about syntax or throwing errors.
<?php
class MyClass{
public function getProperty($propertyName){
$props=get_object_vars($this);
if (array_key_exists($propertyName,$props)){
return $props[$propertyName];
}else{
return FALSE;
}
}
}
?>
I'm trying to have a user-defined list of game-maps. Because I don't know how many maps will be in the array at design time, I'm trying to dynamically create new variables to contain them. Is this even possible? Here's my failed attempt:
<?php
$maplist=array("map1.aamap.xml","map2.aamap.xml"); //edit this list with your maps
$rounds = 3; //times to play each map
/*======No need to edit below========*/
global $last; //store the last played map
class Map
{
public $difficulty;
public $played; //amount of times played
}
foreach($maplist as $i => $element)
{
$element = $map[$i];
$map[$i] = new Map();
}
//snipped other code here
$map[$i]->$played = $x++; //increment the times played counter <-- FAILS HERE
?>
Parser says: Fatal error: Cannot access empty property
Is something like this even feasible in this manner?
There are some errors in your code:
<?php
$maplist=array("map1.aamap.xml","map2.aamap.xml"); //edit this list with your maps
$rounds = 3; //times to play each map
/*======No need to edit below========*/
global $last; //store the last played map
Since you are on the global scope here, not inside a function, there is no need for global.
class Map
{
public $difficulty;
public $played; //amount of times played
}
foreach($maplist as $i => $element)
{
$element = $map[$i];
Is some code missing here? You are not using $element within the loop, so this assignment is not needed.
$map[$i] = new Map();
}
//snipped other code here
$map[$i]->$played = $x++; //increment the times played counter <-- FAILS HERE
The syntax to access a member variable is $object->variable, not $object->$variable. The latter one will evaluate $variable and use the value as variable name (E.g., if $variable = "foo", this will try to access $object->foo).
Use $map[$i]->played = $x++; instead.
When accessing the properties of a class, you don't want to use the $ in front of the property name itself.
Replace $map[$i]->$played = $x++; with $map[$i]->played = $x++; to solve the Fatal error: Cannot access empty property error.
You could override the magic methods to provide dynamic properties if you wish:
public function __get($name)
{
...
}
public function __set($name, $value)
{
...
}
http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members
Within each of these functions you could store the data in some internal array structure.
You don't have to use the $ when accessing properties of an instance. Simple use $map[$i]->played. Have a look on the OOP basics.