Array Push is not working - php

I have created a class in following way
class History
{
private $historyArray;
private $cacheFileNameArray=array();
public function __construct()
{
$this->historyArray=array();
}
public function writeToHistory($query)
{
$cacheFileName=$this->getCacheFileName();
$query=$query.chr(219)."1".chr(219).$cacheFileName;
array_push($this->historyArray,$query);
print_r($this->historyArray);
}
}
Now i have created an object of class History as h,then i'm calling the function writeToHistory() two times with 2 different argument by i wonder that array_push() is not working cause in time of 2nd calling of the function the query should be written in the 1 index of the array but actually the first element of the array is being replaced.Any idea why?

Yes, #shapeshifter is right. it's static.
You could even do
array_push(History->$historyArray, $query);
or
array_push(self::$historyArray, $query);
or
History->$historyArray[] = $query;
PHP manual says "If you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function."
(Note from http://php.net/manual/en/function.array-push.php);

Your historyArray is static. Try,
array_push(self::$historyArray,$query);

Why are you declaing historyArray as an array in the constructor?
Also, where is the function '' defined in your class? if its not defined, that might be causing you trouble... getCacheFileName();
and, give us an example of what you are passing to your writeToHistory function '$query' variable so that we can mode easily see whats going on please
Change you code to the following:
class History
{
private $historyArray = array();
private $cacheFileNameArray= array();
public function __construct()
{
}
public function writeToHistory($query)
{
$cacheFileName=$this->getCacheFileName();
$query=$query.chr(219)."1".chr(219).$cacheFileName;
array_push($this->historyArray,$query);
print_r($this->historyArray);
}
}

Related

unsetting objects in an array based on a bool method

I'm trying to filter an array of objects implementing a specific interface (which simply defines the isComplete(): bool method) based on the result of that method. array_filter doesn't work because it can't call a method on each object to determine whether to filter it (or can it?). I've tried writing a function that takes the splatted array as an argument by reference, this doesn't work either:
function skipIncomplete(CompletableObjectInterface &...$objects): array {
$skipped = [];
foreach ($objects as $index => $item) {
if (!$item->isComplete()) {
$skipped[] = $item->id ?? $index;
unset($objects[$index]);
}
}
return $skipped;
}
The original elements passed in simply don't end up getting unset.
I'm looking for a way that doesn't include creating an entirely new Collection class to hold my CompletableObjects for complexity reasons. I really want to keep the type hint so no one can pass in a generic array, causing runtime errors when the function tries to call $item->isComplete.
Is there any way I can achieve this in PHP 7.3.15?
Added a filter, please comment as to what is wrong with this type of approach:
<?php
interface CompletableObjectInterface {
public function isComplete() : bool;
}
class Foo implements CompletableObjectInterface
{
public function isComplete() : bool
{
return false;
}
}
class Bar implements CompletableObjectInterface
{
public function isComplete() : bool
{
return true;
}
}
$foo = new Foo;
$bar = new Bar;
$incomplete = array_filter([$foo, $bar], function($obj) { return !$obj->isComplete();});
var_dump($incomplete);
Output:
array(1) {
[0]=>
object(Foo)#1 (0) {
}
}
Looks like you got a bit hung up on a wrong understanding of the ... syntax for a variable number of arguments.
You are passing in one array, and the $objects parameter will therefore contain that array in the first index, i.e. in $objects[0].
So in theory you could just change your line
unset($objects[$index]);
to
unset($objects[0][$index]);
However, I do not really see why the variable number of arguments syntax is used at all, since you apparently are just expecting one array of values (objects in this case) as an argument to the function. Therefore I'd recommend you just remove the ... from the argument list and your solution does what you wanted.
Alternatively you can of course add an outer foreach-loop and iterate over all passed "arrays of objects", if that is an use case for you.

How to receive specific interface's array in PHP class method?

I want to receive array of MyInterface as the in the below code.
public function saveMultiple(
\Path\To\MyInterface $attachLinks[]
);
The above code doesn't work.
So please don't tell me that just remove \Path\To\MyInterface and to use a variable $attachLinks. I'm already aware of that but this is something which I require.
There are no generic types in php, so you can not specify type «array of something».
But you may do a trick. Check types of elements in array.
array_walk($attachLinks, function (\Path\To\MyInterface $item) {});
If you wrap it in assert, you will be able to disable this check.
assert('array_walk($attachLinks, function (\Path\To\MyInterface $item) {})');
So far this is what can be done using PHP7. Till date passing arrays with specific type is not possible.
public function saveMultiple(
array $attachLinks
);
It'll now at least make sure that the method only gets array as parameter.
Maybe you can use some type of setter like:
private $attachLinks = [];
public function setter(MyInterface $var)
{
$this->attachLinks[] = $var;
}
And than use a $this->attachLinks in your function
public function saveMultiple() {
print_r($this->attachLinks);
}

How can I make an array of type "class" in PHP?

I have the following class with several properties and a method in PHP (This is simplified code).
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this[$i]->$Name = I find the name using RegExp and return the value to be stored here;
$this[$i]->Family = I find the family using RegExp and return the value to be stored here;
}
}//function
}//class
In the function Fetch_Name(), I want to find all the names and families that is in a text file using RegExp and store them as properties of object in the form of an array. But I don't know how should I define an array of the Member. Is it logical or I should define StdClass or 2-dimension array instead of class?
I found slightly similar discussion here, but a 2 dimensional array is used instead of storing data in the object using class properties.
I think my problem is in defining the following lines of code.
$Member = new Member();
$Member->Fetch_name();
The member that I have defined is not an array. If I do define it array, still it does not work. I did this
$Member[]= new Member();
But it gives error
Fatal error: Call to a member function Fetch_name() on a non-object in
if I give $Member[0]= new Member() then I don't know how to make $Member1 or Member[2] or so forth in the Fetch_Name function. I hope my question is not complex and illogical.
Many thanks in advance
A Member object represents one member. You're trying to overload it to represent or handle many members, which doesn't really make sense. In the end you'll want to end up with an array that holds many Member instances, not the other way around:
$members = array();
for (...) {
$members[] = new Member($name, $family);
}
Most likely you don't really need your Member class to do anything really; the extraction logic should reside outside of the Member class, perhaps in an Extractor class or something similar. From the outside, your code should likely look like this:
$parser = new TextFileParser('my_file.txt');
$members = $parser->extractMembers();
I think you should have two classes :
The first one, Fetcher (or call it as you like), with your function.
The second one, Member, with the properties Name and Family.
It is not the job of a Member to fetch in your text, that's why I would make another class.
In your function, do your job, and in the loop, do this :
for($i = 0; $i < 10; ++$i){
$member = new Member();
$member->setName($name);
$member->setFamily($family);
// The following is an example, do what you want with the generated Member
$this->members[$i] = $member;
}
The problem here is that you are not using the object of type Member as array correctly. The correct format of your code would be:
class Member{
public $Name;
public $Family;
public function Fetch_Name(){
for($i=0;$i<10;$i++){
$this->Name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->Family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
First, $this->Name not $this->$Name because Name is already declared as a member variable and $this->Name[$i] is the correct syntax because $this reference to the current object, it cannot be converted to array, as itself. The array must be contained in the member variable.
L.E: I might add that You are not writing your code according to PHP naming standards. This does not affect your functionality, but it is good practice to write your code in the standard way. After all, there is a purpose of having a standard.
Here you have a guide on how to do that.
And I would write your code like this:
class Member{
public $name;
public $family;
public function fetchName(){
for($i=0;$i<10;$i++){
$this->name[$i] = 'I find the name using RegExp and return the value to be stored here';
$this->family[$i] = 'I find the family using RegExp and return the value to be stored here';
}
}
}
L.E2: Seeing what you comented above, I will modify my answer like this:
So you are saying that you have an object of which values must be stored into an array, after the call. Well, after is the key word here:
Initialize your object var:
$member = new Memeber();
$memebr->fechNames();
Initialize and array in foreach
$Member = new Member();
foreach ($Member->Name as $member_name){
$array['names'][] = $member_name;
}
foreach ($Member->Family as $member_family) {
$array['family'][] = $member_family;
}
var_dump($array);
Is this more of what you wanted?
Hope it helps!
Keep on coding!
Ares.

PHP: Problems Instantiating Class

I try to create new object of a class called Isolate (this class is used to prevent XSS and other attacks via htmlspecialchars and so on).
So, I do it like this:
$data['name'] = $_POST['name'];
$data = $isolate->isolateArr($data);
And my Isolate class look like this:
class Isolate {
public function isolate($var) {
$iVar = htmlspecialchars($var);
$iVar = mysql_real_escape_string($iVar);
$iVar = stripcslashes($iVar);
return $iVar;
}
public function isolateArr($arr) {
foreach($arr as &$instance) {
$instance = $this->isolate($instance);
}
unset($instance);
return $arr;
}
But as the result I have a warning like Missing argument 1 for Isolate. As I understand, it asks me for the argument for the first function, but I do not need to call the first one, I need to call the second (because I have an array in this case).
So, why does it always ask for the first function argument? There in no any __construct method, what is the point?
Thank you in advance!
isolate() is your constructor method.
http://www.php.net/manual/en/language.oop5.decon.php
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, and the class did not inherit one from a parent class, it will search for the old-style constructor function, by the name of the class.

Magento Varien Object not Saving data

I'm trying to use setData in my Address object.
Here is the code:
//code inside another class
$this->getAddress()->setData('abc', 'abc')->collectShippingRates()->save();
class Mage_Sales_Model_Quote_Address extends Mage_Customer_Model_Address_Abstract
{
...
public function collectShippingRates()
{
...
$found = $this->requestShippingRates();
...
return $this;
}
public function requestShippingRates(Mage_Sales_Model_Quote_Item_Abstract $item = null)
{
//I knkow it's getting here, because when I echo 'blablabla', it works.
//When I use $this->setData('abc', 'abc') here, the code bellow print 'abc'
//The problem is when I use setData outside the class
echo $this->getData('abc');exit; //prints nothing
...
}
...
}
As you can see, I setData in my Address model, but inside the class getData returns nothing.
Can someone please explain what's happening?
When I try to use Mage::register, it does not work too.
Possible avenues of exploration.
Your call to getAddress isn't returning a Mage_Sales_Model_Quote_Address object, or is returning a different instance of an address object.
Your call to setData('abc', 'abc') happens later in Magento's code execution than the first call to requestShippingRates.
Code between your call to getAddress and the execution of requestShippingRates is re-instantiating or initializing the address object.
Based on your comments about Mage::register, my money is on number two.

Categories