showing the [Object Object] in Angular [duplicate] - php

I am trying to alert a returned value from a function and I get this in the alert:
[object Object]
Here is the JavaScript code:
<script type="text/javascript">
$(function ()
{
var $main = $('#main'),
$1 = $('#1'),
$2 = $('#2');
$2.hide(); // hide div#2 when the page is loaded
$main.click(function ()
{
$1.toggle();
$2.toggle();
});
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible());
});
function whichIsVisible()
{
if (!$1.is(':hidden')) return $1;
if (!$2.is(':hidden')) return $2;
}
});
</script>
whichIsVisible is the function which I am trying to check on.

As others have noted, this is the default serialisation of an object. But why is it [object Object] and not just [object]?
That is because there are different types of objects in Javascript!
Function objects:
stringify(function (){}) -> [object Function]
Array objects:
stringify([]) -> [object Array]
RegExp objects
stringify(/x/) -> [object RegExp]
Date objects
stringify(new Date) -> [object Date]
… several more …
and Object objects!
stringify({}) -> [object Object]
That's because the constructor function is called Object (with a capital "O"), and the term "object" (with small "o") refers to the structural nature of the thingy.
Usually, when you're talking about "objects" in Javascript, you actually mean "Object objects", and not the other types.
where stringify should look like this:
function stringify (x) {
console.log(Object.prototype.toString.call(x));
}

The default conversion from an object to string is "[object Object]".
As you are dealing with jQuery objects, you might want to do
alert(whichIsVisible()[0].id);
to print the element's ID.
As mentioned in the comments, you should use the tools included in browsers like Firefox or Chrome to introspect objects by doing console.log(whichIsVisible()) instead of alert.
Sidenote: IDs should not start with digits.

[object Object] is the default toString representation of an object in javascript.
If you want to know the properties of your object, just foreach over it like this:
for(var property in obj) {
alert(property + "=" + obj[property]);
}
In your particular case, you are getting a jQuery object. Try doing this instead:
$('#senddvd').click(function ()
{
alert('hello');
var a=whichIsVisible();
alert(whichIsVisible().attr("id"));
});
This should alert the id of the visible element.

You can see value inside [object Object] like this
Alert.alert( JSON.stringify(userDate) );
Try like this
realm.write(() => {
const userFormData = realm.create('User',{
user_email: value.username,
user_password: value.password,
});
});
const userDate = realm.objects('User').filtered('user_email == $0', value.username.toString(), );
Alert.alert( JSON.stringify(userDate) );
reference
https://off.tokyo/blog/react-native-object-object/

Basics
You may not know it but, in JavaScript, whenever we interact with string, number or boolean primitives we enter a hidden world of object shadows and coercion.
string, number, boolean, null, undefined, and symbol.
In JavaScript there are 7 primitive types: undefined, null, boolean, string, number, bigint and symbol. Everything else is an object. The primitive types boolean, string and number can be wrapped by their object counterparts. These objects are instances of the Boolean, String and Number constructors respectively.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
If primitives have no properties, why does "this is a string".length return a value?
Because JavaScript will readily coerce between primitives and objects. In this case the string value is coerced to a string object in order to access the property length. The string object is only used for a fraction of second after which it is sacrificed to the Gods of garbage collection – but in the spirit of the TV discovery shows, we will trap the elusive creature and preserve it for further analysis…
To demonstrate this further consider the following example in which we are adding a new property to String constructor prototype.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
By this means primitives have access to all the properties (including methods) defined by their respective object constructors.
So we saw that primitive types will appropriately coerce to their respective Object counterpart when required.
Analysis of toString() method
Consider the following code
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
As discussed above, what's really happening is when we call toString() method on a primitive type, it has to be coerced into its object counterpart before it can invoke the method.
i.e. myNumber.toString() is equivalent to Number.prototype.toString.call(myNumber) and similarly for other primitive types.
But what if instead of primitive type being passed into toString() method of its corresponding Object constructor function counterpart, we force the primitive type to be passed as parameter onto toString() method of Object function constructor (Object.prototype.toString.call(x))?
Closer look at Object.prototype.toString()
As per the documentation,
When the toString method is called, the following steps are taken:
If the this value is undefined, return "[object Undefined]".
If the this value is null, return "[object Null]".
If this value is none of the above, Let O be the result of calling toObject passing the this value as the argument.
Let class be the value of the [[Class]] internal property of O.
Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Understand this from the following example
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
References:
https://es5.github.io/x15.2.html#x15.2.4.2
https://es5.github.io/x9.html#x9.9
https://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/

It's the value returned by that object's toString() function.
I understand what you're trying to do, because I answered your question yesterday about determining which div is visible. :)
The whichIsVisible() function returns an actual jQuery object, because I thought that would be more programmatically useful. If you want to use this function for debugging purposes, you can just do something like this:
function whichIsVisible_v2()
{
if (!$1.is(':hidden')) return '#1';
if (!$2.is(':hidden')) return '#2';
}
That said, you really should be using a proper debugger rather than alert() if you're trying to debug a problem. If you're using Firefox, Firebug is excellent. If you're using IE8, Safari, or Chrome, they have built-in debuggers.

[object Object] is the default string representation of a JavaScript Object. It is what you'll get if you run this code:
alert({}); // [object Object]
You can change the default representation by overriding the toString method like so:
var o = {toString: function(){ return "foo" }};
alert(o); // foo

I think the best way out is by using JSON.stringify() and passing your data as param:
alert(JSON.stringify(whichIsVisible()));

You have a javascript object
$1 and $2 are jquery objects, maybe use alert($1.text()); to get text or alert($1.attr('id'); etc...
you have to treat $1 and $2 like jQuery objects.

You are trying to return an object. Because there is no good way to represent an object as a string, the object's .toString() value is automatically set as "[object Object]".

Consider the following example:
const foo = {};
foo[Symbol.toStringTag] = "bar";
console.log("" + foo);
Which outputs
[object bar]
Basically, any object in javascript can define a property with the tag Symbol.toStringTag and override the output.
Behind the scenes construction of a new object in javascript prototypes from some object with a "toString" method. The default object provides this method as a property, and that method internally invokes the tag to determine how to coerce the object to a string. If the tag is present, then it's used, if missing you get "Object".
Should you set Symbol.toStringTag? Maybe. But relying on the string always being [object Object] for "true" objects is not the best idea.

The object whose class is Object seems quite different from the usual class instance object, because it acts like an associative array or list: it can be created by simple object literals (a list of keys and properties), like this: let obj={A:'a',B:'b'}; and because it looks very like this same literal notation when displayed in the Developer Tools Console pane and when it is converted to a JSON string.
But, in fact, the only real difference in objects of other classes (which are derived or extended from Object) is that other classes usually have constructors and methods (these are all functions), in addition to properties (which are variables). A class instance object is allocated using the 'new' operator, and its properties and methods are accessible through the 'this' variable. You can also access the underlying static functions that are copied to each new instance by using the 'prototype' property, and even extend system classes by adding new functions to their prototype object.
The Array object is also derived from Object and is frequently used: it is an ordered, 0-indexed array of variable values.
Object objects, unlike Arrays and other classes are treated simply as associative arrays (sometimes considered ordered, and sometimes considered unordered).

Related

What does the generic "stdClass" stand for in PHP? [duplicate]

Please define what stdClass is.
stdClass is just a generic 'empty' class that's used when casting other types to objects. Despite what the other two answers say, stdClass is not the base class for objects in PHP. This can be demonstrated fairly easily:
class Foo{}
$foo = new Foo();
echo ($foo instanceof stdClass)?'Y':'N';
// outputs 'N'
I don't believe there's a concept of a base object in PHP
stdClass is PHP's generic empty class, kind of like Object in Java or object in Python (Edit: but not actually used as universal base class; thanks #Ciaran for pointing this out).
It is useful for anonymous objects, dynamic properties, etc.
An easy way to consider the StdClass is as an alternative to associative array. See this example below that shows how json_decode() allows to get an StdClass instance or an associative array.
Also but not shown in this example, SoapClient::__soapCall returns an StdClass instance.
<?php
//Example with StdClass
$json = '{ "foo": "bar", "number": 42 }';
$stdInstance = json_decode($json);
echo $stdInstance->foo . PHP_EOL; //"bar"
echo $stdInstance->number . PHP_EOL; //42
//Example with associative array
$array = json_decode($json, true);
echo $array['foo'] . PHP_EOL; //"bar"
echo $array['number'] . PHP_EOL; //42
See Dynamic Properties in PHP and StdClass for more examples.
stdClass is a another great PHP feature.
You can create a anonymous PHP class.
Lets check an example.
$page=new stdClass();
$page->name='Home';
$page->status=1;
now think you have a another class that will initialize with a page object and execute base on it.
<?php
class PageShow {
public $currentpage;
public function __construct($pageobj)
{
$this->currentpage = $pageobj;
}
public function show()
{
echo $this->currentpage->name;
$state = ($this->currentpage->status == 1) ? 'Active' : 'Inactive';
echo 'This is ' . $state . ' page';
}
}
Now you have to create a new PageShow object with a Page Object.
Here no need to write a new Class Template for this you can simply use stdClass to create a Class on the fly.
$pageview=new PageShow($page);
$pageview->show();
Also worth noting, an stdClass object can be created from the use of json_decode() as well.
Using stdClass you can create a new object with it's own properties.
Consider the following example that represents the details of a user as an associative array.
$array_user = array();
$array_user["name"] = "smith john";
$array_user["username"] = "smith";
$array_user["id"] = "1002";
$array_user["email"] = "smith#nomail.com";
If you need to represent the same details as the properties of an object, you can use stdClass as below.
$obj_user = new stdClass;
$obj_user->name = "smith john";
$obj_user->username = "smith";
$obj_user->id = "1002";
$obj_user->email = "smith#nomail.com";
If you are a Joomla developer refer this example in the Joomla docs for further understanding.
Likewise,
$myNewObj->setNewVar = 'newVal';
yields a stdClass object - auto casted
I found this out today by misspelling:
$GLOBASLS['myObj']->myPropertyObj->myProperty = 'myVal';
Cool!
stdClass is not an anonymous class or anonymous object
Answers here includes expressions that stdClass is an anonymous class or even anonymous object. It's not a true.
stdClass is just a regular predefined class. You can check this using instanceof operator or function get_class. Nothing special goes here. PHP uses this class when casting other values to object.
In many cases where stdClass is used by the programmers the array is better option, because of useful functions and the fact that this usecase represents the data structure not a real object.
The reason why we have stdClass is because in PHP there is no way to distinguish a normal array from an associate array (like in Javascript you have {} for object and [] for array to distinguish them).
So this creates a problem for empty objects. Take this for example.
PHP:
$a = [1, 2, 3]; // this is an array
$b = ['one' => 1, 'two' => 2]; // this is an associate array (aka hash)
$c = ['a' => $a, 'b' => $b]; // this is also an associate array (aka hash)
Let's assume you want to JSON encode the variable $c
echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': {one: 1, two: 2}}
Now let's say you deleted all the keys from $b making it empty. Since $b is now empty (you deleted all the keys remember?), it looks like [] which can be either an array or object if you look at it.
So if you do a json_encode again, the output will be different
echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': []}
This is a problem because we know b that was supposed to be an associate array but PHP (or any function like json_encode) doesn't.
So stdClass comes to rescue. Taking the same example again
$a = [1, 2, 3]; // this is an array
$b = (object) ['one' => 1, 'two' => 2]; // this makes it an stdClass
$c = ['a' => $a, 'b' => $b]; // this is also an associate array (aka hash)
So now even if you delete all keys from $b and make it empty, since it is an stdClass it won't matter and when you json_encode it you will get this:
echo json_encode($c);
// outputs => {'a': [1,2,3], 'b': {}}
This is also the reason why json_encode and json_decode by default return stdClass.
$c = json_decode('{"a": [1,2,3], "b": {}}', true); //true to deocde as array
// $c is now ['a' => [1,2,3], 'b' => []] in PHP
// if you json_encode($c) again your data is now corrupted
Its also worth noting that by using Casting you do not actually need to create an object as in the answer given by #Bandula. Instead you can simply cast your array to an object and the stdClass is returned. For example:
$array = array(
'Property1'=>'hello',
'Property2'=>'world',
'Property3'=>'again',
);
$obj = (object) $array;
echo $obj->Property3;
Output: again
stdClass objects in use
The stdClass allows you to create anonymous classes and
with object casting you can also access keys of an associative array in OOP style. Just like you would access the regular object property.
Example
class Example {
private $options;
public function __construct(Array $setup)
{
// casting Array to stdClass object
$this->options = (object) $setup;
// access stdClass object in oop style - here transform data in OOP style using some custom method or something...
echo $this->options->{'name'}; // ->{'key'}
echo $this->options->surname; // ->key
}
}
$ob1 = new Example(["name" => "John", "surname" => "Doe"]);
will echo
John Doe
Actually I tried creating empty stdClass and compared the speed to empty class.
class emp{}
then proceeded creating 1000 stdClasses and emps... empty classes were done in around 1100 microseconds while stdClasses took over 1700 microseconds. So I guess its better to create your own dummy class for storing data if you want to use objects for that so badly (arrays are a lot faster for both writing and reading).
php.net manual has a few solid explanation and examples contributed by users of what stdClass is, I especially like this one http://php.net/manual/en/language.oop5.basic.php#92123, https://stackoverflow.com/a/1434375/2352773.
stdClass is the default PHP object. stdClass has no properties,
methods or parent. It does not support magic methods, and implements
no interfaces.
When you cast a scalar or array as Object, you get an instance of
stdClass. You can use stdClass whenever you need a generic object
instance.
stdClass is NOT a base class! PHP classes do not automatically inherit
from any class. All classes are standalone, unless they explicitly
extend another class. PHP differs from many object-oriented languages
in this respect.
You could define a class that extends stdClass, but you would get no
benefit, as stdClass does nothing.
Please bear in mind that 2 empty stdClasses are not strictly equal. This is very important when writing mockery expectations.
php > $a = new stdClass();
php > $b = new stdClass();
php > var_dump($a === $b);
bool(false)
php > var_dump($a == $b);
bool(true)
php > var_dump($a);
object(stdClass)#1 (0) {
}
php > var_dump($b);
object(stdClass)#2 (0) {
}
php >
If you wanted to quickly create a new object to hold some data about a book. You would do something like this:
$book = new stdClass;
$book->title = "Harry Potter and the Prisoner of Azkaban";
$book->author = "J. K. Rowling";
$book->publisher = "Arthur A. Levine Books";
$book->amazon_link = "http://www.amazon.com/dp/0439136369/";
Please check the site - http://www.webmaster-source.com/2009/08/20/php-stdclass-storing-data-object-instead-array/ for more details.
stdclass is a way in which the php avoid stopping interpreting the script when there is some data must be put in a class , but
unfortunately this class was not defined
Example :
return $statement->fetchAll(PDO::FETCH_CLASS , 'Tasks');
Here the data will be put in the predefined 'Tasks' . But, if we did the code as this :
return $statement->fetchAll(PDO::FETCH_CLASS );
then the php will put the results in stdclass .
simply php says that : look , we have a good KIDS[Objects] Here but without Parents . So , we will send them to a infant child Care Home stdclass :)
stClass is an empty class created by php itself , and should be used by php only,
because it is not just an "empty" class ,
php uses stdClass to convert arrays to object style
if you need to use stdClass , I recommend two better options :
1- use arrays (much faster than classes)
2- make your own empty class and use it
//example 1
$data=array('k1'=>'v1' , 'k2'=>'v2',....);
//example 2
//creating an empty class is faster than instances an stdClass
class data={}
$data=new data();
$data->k1='v1';
$data->k2='v2';
what makes someone to think about using the object style instead of array style???
You can also use object to cast arrays to an object of your choice:
Class Example
{
public $name;
public $age;
}
Now to create an object of type Example and to initialize it you can do either of these:
$example = new Example();
$example->name = "some name";
$example->age = 22;
OR
$example = new Example();
$example = (object) ['name' => "some name", 'age' => 22];
The second method is mostly useful for initializing objects with many properties.
stdClass in PHP is classic generic class. It has no built-in properties or methods. Basically, It's used for casting the types, creating objects with dynamic properties, etc. If you have the javascript background, You can determine as
$o = new \stdClass();
is equivalent to
const o = {};
It creates empty object, later populated by the program control flow.

Kotlin equivalent of php's $object->{$key}

I have the following Kotlin class:
class Program {
#SerializedName("hrs0")
var nHrs0: Int? = null
#SerializedName("hrs1")
var nHrs1: Int? = null
}
I need to reference a variable from this class, but I only have the variable name as a string. Normally, I would use it as so:
Program.nHrs0 = 5;
I need to be able to assign that value, but I only have the string equivalent of the variable's name. In php, I would do something like this:
$program->{$variableName}
How can this be done in Kotlin:
variableName = "nHrs0"
Program.{variableName}
Thanks
In this case, you would use a Map and after apply values to Program:
// create Map
val programMap = mutableMapOf<String, Int>()
// apply value to key
programMap["nHrs0"] = 5
val program = Program()
// get value from key
program.nHrs0 = programMap["nHrs0"]
You can do this with the Kotlin reflection API. The first step is to add the Kotlin reflection runtime to your project since it is not included by default because of its size/overhead and relatively rare use. I Use Kotlin 1.3.50 which is the latest version right now. Change to the version you use if you use an older version:
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.50'
This is how you use this API in this case:
// Obtain a reference to the nHrs0 member
val nHrs0Member = Program::class.members.find { it.name == "nHrs0" }
// Since it is a property (var), we can and must cast it to
// KMutableProperty to use it
val nHrs0Property = nHrs0Member as KMutableProperty
// Kotlin properties are not really JVM fields. They consists
// of a getter (for 'val' and 'var') and a setter (only for
// 'var'). So to set this property, we need to obtain a reference
// to the setter
val nHrs0Setter = nHrs0Property.setter
// Create an instance to perform our operations on
val p = Program()
// Use our setter to set the property "nHrs0" on
// instance 'p' to 5
nHrs0Setter.call(p, 5)
// Prove that the property was set
println("p.nHrs0=${p.nHrs0}") // Prints p.nHrs0=5
For more information on how properties work in Kotlin, refer to the official docs on Properties and Fields. For more information on the reflection API, refer to the official docs on Reflection

How to assert parameter attribute sub-structures in PHPUnit mock call expectations

I am testing an parameter sent to a mocked event handler. The parameter is an object of "Event" sub-type, which itself has some data nested inside it. I want to test the Event and its substructure matches the fixture data I've injected into the code through various mocks.
I can test the "top level" of the event easily enough: the classname, and simple attributes like an event name string. I can also test that an attribute contains the same object, which I believe implicitly tests all the substructure of the object.
The problem I'm having is some of the sub-structure in a more complex example is causing the test to fail but it's irrelevant, so I want to cherry-pick specific properties of the sub-structure, and not just identity-compare the entire object.
I feel like I'm missing something in the attribute assertions: how to access the parameter that the "with" refers to - as variable. Then I could pass it into some of the assert methods like attributeEqualTo which require the item under test to be passed in. Perhaps these just cannot be used in the fluent case I'm using?
I'd like to check the event.data is a certain class.
I'd like to check the event.data.thing1 == X
I'd like to check the event.data.thing2 == Y
and so on.
Simplified code:
class MyEventData{
public $thing1;
public $thing2;
}
class MyEvent{
public $data;
}
// An event gets fired containing this in the tests
$eventData = new MyEventData(1,2);
$this->eventMock->expects($this->exactly(3))
->method('fire')
->with(
$this->logicalAnd(
// THIS WORKS OK
$this->isInstanceOf('\MyApp\MyEvents\SomeEvent'),
// THIS WORKS OK
$this->attributeEqualTo ('name', SomeEvent::EVENT_NAME),
// THIS WORKS in simplified cases only
$this->attributeEqualTo ('data', $eventData),
// HOW DO I GET THE "WITH" PARAMETER CONTEXT "INTO" THE THIRD PARAMETER?
$this->assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', -classOrObject- ),
// Then how can I test with attribute data.thing1 == 1 and data.thing2 = 2
)
);
I've got it to work using the callback constraint, but it feels like I've now stepped off the path and lost the power of PHPUnit - I can't seem to use the assertion helpers here anymore.
e.g. If the accumulated tests return false, I don't get any details in the output log beyond "Expectation failed for ... and is accepted by specified callback".
$this->callback(function($subject){
$b = true;
// I tried using this constraint but can't access (autoload) this class? So is it not supposed to be used directly?
//$c = new PHPUnit_Framework_Constraint_IsInstanceOf('\MyApp\MyEvents\MyEventData');
// return $c->matches(subject);
// this is the right assert, but it doesn't return the result, so I cannot use it in a callback constraint.
\PHPUnit_Framework_Assert::assertAttributeInstanceOf('\MyApp\MyEvents\MyEventData', 'data', $subject);
// This works but seems very "Manual"
$b = $b && get_class($subject->data) == '\MyApp\MyEvents\MyEventData';
$b = $b && $subject->data->thing1 == 1;
$b = $b && $subject->data->thing2 == 1;
return $b;
})

Not getting query string value using angular.js

I have a URL like this http://localhost/phpdemo/edit_data.php?edt_id=1. Here I need the query string value which is 1. By using Angular.js, I am getting the following output in browser's console.
id is : Object {}
My code is given below.
update.js:
var app=angular.module("edit_data", []);
app.controller("updateController",function($scope,$http,$location){
$scope.errors = [];
$scope.msgs = [];
var id=$location.search();
console.log("id is :",id);
$http.get('js/edit.php',{"user_id":$location.hash()}).success(function(response){
console.log('response',response);
});
$scope.update_data=function(){
$http.post('js/update.php',{"first_name":$scope.first_name,"last_name":$scope.last_name,"city":$scope.city}
).success(function(data, status, headers, config){
if(data.msg!=''){
$scope.msgs.push(data.msg);
}else{
$scope.errors.push(data.error);
}
}).error(function(data, status) { // called asynchronously if an error occurs
// or server returns response with an error status.
$scope.errors.push(status);
});
}
});
Please help me to resolve this issue.
$location.search() will return an object of key-value pairs, the same pairs as the query string. A key that has no value is just stored in the object as true. In this case, the object would be:
var id=$location.search().edt_id;
Location service Search Little Brief
search(search, [paramValue]);
This method is getter / setter.
Return search part (as object) of current url when called without any parameter.
Change search part when called with parameter and return $location.
// given url http://example.com/#/some/path?foo=bar&baz=xoxo
var searchObject = $location.search();
// => {foo: 'bar', baz: 'xoxo'}
// set foo to 'yipee'
$location.search('foo', 'yipee');
// $location.search() => {foo: 'yipee', baz: 'xoxo'}
This $location.search(); return an array, so
console.log("id is :",id[0]);
Can you try with above.
UPDATE:
$location.search()['edt_id']
It must return the value 1

The in_array doesn't compare my converted objects as it is supposed to

I'm developping a website, where if a user changes some data, it should be stored on the background, to see who did last change and what etc... . I have 1 object called Event, but the data onscreen is devided into 2 tabs (Client and Event). After the submit, I get all the fields and put the data in the object. I have this self made function to compare the values in the new boject with the values of the old object:
function createArrayReturnDiff($obj1, $obj2) {
$helpArray1 = (array) $obj1; //convert object to array
$helpArray2 = (array) $obj2; //convert object to array
$help = array_diff_assoc($helpArray2, $helpArray1); //Computes the difference of arrays with additional index check
return $help;
}
Now this works all fine, I get an array returned with names of the field and the new value.
But here comes the tricky part. After the return of this array, I loop trough it I want to check which tab the value was on in order to give beter user feedback later. So if the value is on Cleint or Event tab. Now I made 2 arrays where I describe all the fields in each tab.
$tabKlant = array('Evenementfirmanaam', 'Evenementaanspreking', 'Evenementcontactpersoon', 'Evenementcontactpersoonstraat', 'Evenementcontactpersoongemeente', 'Evenementcontactpersoonland', 'Evenementcontactpersoonmail', 'Evenementcontactpersoontel', 'Evenementgeldigheidsdatum', 'Evenementfacturatiegegevens', 'Evenementfactuur_mededeling', 'Evenementbestelbon', 'Evenementreferentie');
$tabEvenement = array('Evenementstartdatum', 'Evenementeinddatum', 'Evenementnaam', 'Evenementfeestlocatie', 'Evenementcontactfeestlocatie', 'Evenementaantal', 'Evenementact_speeches_opm', 'Evenementdj', 'Evenementinleiding');
Now my code to check:
foreach ($help as $key => $value) {
if (in_array($key, $tabEvent)) {
$tab = "Event";
} else if (in_array($key, $tabClient)) {
$tab = "Client";
} else {
$tab = "";
}
}
Now what I tried to change was Evenementfirmanaam, so the $help array contains values with key = Evenementfirmanaam and value = 'xxxx'. Everything looks like it is supposed to work. But for some reason, it can't find the value in the in_array of my foreach.
After I tried to write away data to the database. I used a mysqli_real_escape_string on the $key of my help array (firmanaam in this case) and I found out it is creating the string like: '\0Evenement\0firmanaam' . I have no idea why the \0 are added, but I have a feeling this is the reason why the in_array function won't compare my values properly. Does anyone have an idea what the problem might be?
The problem is that the firmanaam property of your Evenement class (which $obj1 and $obj2 look like to be instances of) is private, which results in the cast to array creating special keys:
If an object is converted to an array, the result is an array whose
elements are the object's properties. The keys are the member variable
names, with a few notable exceptions: integer properties are
unaccessible; private variables have the class name prepended to the
variable name; protected variables have a '*' prepended to the
variable name. These prepended values have null bytes on either side.
This can result in some unexpected behaviour.
In essence, you are being punished for violating the logical design of your class: if $firmanaam is private the outside world should not have any access to its value. The cast to array does allow you to get the value but you really should not do this.
Since you are using Evenement to encapsulate and hide data members, do it all the way. If you want access to those members, provide for and use a getter. If you want to compare two instances with specific semantics, add a comparison method to the class.

Categories