I'm wondering about this weird thing:
public function getAllCustomers()
{
$customers = $this->redis->keys("customer:*");
foreach ($customers as $value) {
return new \Customer($this->redis->hget($value,"name"),$this->redis->hget($value,"id"),$this->redis->hget($value,"email"));
}
}
This method returns all customers from my database.
But if I try to loop through all of these customers:
foreach ($customerController->getAllCustomers() as $customer) {
var_dump($customer);
}
The getName() method is not found. var_dump returns:
NULL
NULL
NULL
Customer class:
class Customer {
var $name;
var $id;
var $email;
function __construct($name, $id,$email) {
$this->name = $name;
$this->id = $id;
$this->email = $email;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getEmail()
{
return $this->email;
}
public function __toString()
{
return "";
}
}
I'm pretty new to PHP and don't understand why I can't access the Customer object's field.
Your Problem: you do not return array of customer but only one. You getting null because your function return only 1 object -> and in PHP, when using foreach loop on object you get his fields -> and the fields do not have the getName function.
Solution: Init customer array, populate it and return from the function.
public function getAllCustomers()
{
$customers = $this->redis->keys("customer:*");
$customersObjs = array();
foreach ($customers as $value) {
$customersObjs[] = new Customer($this->redis->hget($value,"name"),$this->redis->hget($value,"id"),$this->redis->hget($value,"email")));
}
return $customersObjs;
}
Now you have array of the customersObjs you can loop on with:
foreach ($customerController->getAllCustomers() as $customer) {
echo $customer->getName();
}
Solution :
public function getAllCustomers()
{
$customers = $this->redis->keys("customer:*");
$custumersArray = array();
foreach ($customers as $value) {
$custumersArray[] = \Customer($this->redis->hget($value,"name"),$this->redis->hget($value,"email"),$this->redis->hget($value,"id"));
}
return $custumersArray;
}
the problem was that you are returning a single array but not a array list.
Related
My entity :
class User{
id : int
name : string
boss : User()
}
I want to create a function that return an array() of users that work under a giving user.
example :
public function MyEmployers( User $user , array $usersList )
{
$myEmployers = array();
...
return $myEmployers;
}
$results = $this->myEmployers ( $employer1 , $allEmployers)
dump ( $results );
$results = [ 4 , 5 , 6 ];
I found a solution if someone can improve it feel free :
public $tree = array();
public function MyEmployers(User $user)
{
$superior_key_id = array();
$all_users = $this->getallusers();
$id = $user->getId();
foreach ($all_users as $user) {
if ($user->getSuperior())
$superior_key_id[$user->getSuperior()->getId()][] = $user;
}
$this->getSubEmployee($this->getUser(), $superior_key_id);
return ($this->tree);
}
public function getSubEmployee($user, $superior_key_id)
{
if (isset($superior_key_id[$user->getId()])) {
foreach ($superior_key_id[$user->getId()] as $user) {
$this->tree[] = $user;
$this->getSubEmployee($user, $superior_key_id);
}
}
return $user;
}
this one will get all bosses if you're interested :
public function MyBosses(User $user)
{
$bosses = array();
while ($user->getSuperior()) {
array_push($bosses, $user->getSuperior());
$user = $user->getSuperior();
}
return $bosses;
}
You could set up a one-to-many relationship between boss and employee
So you're user class could look like:
class User{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="employee")
*/
private $boss;
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="boss")
*/
private $employees;
public function __construct()
{
$this->employees = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* #return Collection|employees[]
*/
public function getEmployees(): Collection
{
return $this->employees;
}
public function addEmployee(employee $employee): self
{
if (!$this->employees->contains($employee)) {
$this->employees[] = $employee;
}
return $this;
}
public function removeEmployee(employee $employee): self
{
if ($this->employees->contains($employee)) {
$this->employees->removeElement($employee);
}
return $this;
}
public function getBoss(): ?Usesr
{
return $this->boss;
}
public function setBoss(?User $boss): self
{
$this->boss = $boss;
return $this;
}
}
You would need to set up the database relationship with the symfony make:entity command.
To get all employeers under a user, you could do something like:
function getAllEmployeesUnder(User $user)
{
$allEmployees = [];
foreach ($user->getEmployees as $employee) {
$allEmployees[] = $employee;
$allEmployees = array_merge($allEmployees, $this->getAllEmployeesUnder($employee));
}
return $allEmployees;
}
I have a problem.. When I execute this code:
public function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
private static $users = $this->korisnici();
It gives me this error: syntax error, unexpected '$this' (T_VARIABLE)..
Can someone help me, how can I call this function?
Here's my whole class:
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
public $arr;
public function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
public $users = $this->korisnici();
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
}
}
return null;
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
I'm trying to change this default model from Yii Framework so I can login using database...
Looks like you have copied it from a class. The following will work like a regular function. Still not sure where you get $modelk = new Korisnici(); from
function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
print_r(korisnici());
EDIT: After looking at your whole class:
You need to use the __construct method.
public function __construct()
{
$this->users = $this->korisnici();
}
I'm trying to set my first steps into the OO PHP world. What I'm trying to do is make a class that validates my form input. I know what input fields I need in my entire website and want to make a switch, to do the right thing based on the input field. Lets say we have the input field named 'email', and we have a form for that etc...
First, what I want to do is try to read the $_post names with array_key() function, based on that I have a switch.
Here is my code:
public function __construct ( $var ) {
$this->arraykeys = array_keys($var);
$this->error = false;
$this->message = array();
}
public function check() {
foreach ($this->arraykeys as $i => $value)
{
switch ($value)
{
case 'email' :
$checkmail = new checkEmail($_POST);
$checkmail->chkEmail($_POST['email']);
if ($checkmail->chkEmail($_POST['email']) == false)
{
array_push($this->message, 'Cannot validate emailadres');
}
break;
}
}
// print_r($this->field);
}
The check works, but somehow the message array stays empty after an error!
I tried everything, but I just can't get it on to the screen!
Please help!
Thanks!!
Before you make use of OOP you actually need to have some of the more basic objects that enable you to let your form processing come to live, for example object oriented validation of form fields within PHP superglobals with error messages:
Just exemplary:
// defining the interfaces and classes of the form values and validation, form field
// and fields
Interface FormValue
{
public function getValue();
}
interface FormValueValidator
{
/**
* #param FormValue $value
* #return bool
*/
public function validate(FormValue $value);
}
class NamedFormValue implements FormValue
{
private $name;
private $value;
public function __construct(array $data, $name, $default = null)
{
$this->name = $name;
$this->value = isset($data[$name]) ? $data[$name] : $default;
}
public function getValue()
{
return $this->value;
}
public function getName()
{
return $this->name;
}
}
class EmailValidator implements FormValueValidator
{
public function validate(FormValue $value)
{
$result = filter_var((string) $value->getValue(), FILTER_VALIDATE_EMAIL);
return is_string($result);
}
}
class FormFieldFactory
{
/**
* #param $name
* #param array $field
* #return FormField
*/
public function create($name, array $field)
{
$validatorClass = sprintf('%sValidator', #$field['validator']);
$validator = new $validatorClass;
$formField = new FormField($name);
$formField->setValidator($validator);
$formField->setErrorMessage($field['error_msg']);
return $formField;
}
}
class FormField
{
private $name;
/**
* #var FormValueValidator
*/
private $validator;
private $errorMessage;
/**
* #var FormValue
*/
private $value;
public function __construct($name)
{
$this->name = $name;
}
public function setValidator(FormValueValidator $validator)
{
$this->validator = $validator;
}
public function isValid()
{
return $this->validator->validate($this->value);
}
public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
}
public function getErrorMessage() {
return $this->errorMessage;
}
public function setValue(FormValue $value)
{
$this->value = $value;
}
/**
* #return FormValue
*/
public function getValue()
{
return $this->value;
}
}
class FormFields extends IteratorIterator
{
private $fieldFactory;
private $invalidFields;
public function __construct(array $definitions, $fieldFactory)
{
parent::__construct(new ArrayIterator($definitions));
$this->fieldFactory = $fieldFactory;
}
public function current()
{
$name = $this->getInnerIterator()->key();
$definition = $this->getInnerIterator()->current();
return $this->fieldFactory->create($name, $definition);
}
public function valid()
{
return $this->getInnerIterator()->valid();
}
/**
* #param array $data
* #return bool true on success, false on validation error
*/
public function validateOn(array $data)
{
$this->invalidFields = array();
foreach($this as $name => $field) {
/* #var $field FormField */
$value = new NamedFormValue($data, $name);
$field->setValue($value);
$valid = $field->isValid();
$valid || ($this->invalidFields[$name] = $field);
}
return 0 === count($this->invalidFields);
}
/**
* #return FormField[]
*/
public function getInvalidFields()
{
return $this->invalidFields;
}
}
// defining the form in array notation:
$form = array(
'fields' => array(
'email' => array(
'validator' => 'Email',
'error_msg' => 'Cannot validate emailadress',
),
),
);
// processing the form validation
$messages = array();
$fields = new FormFields($form['fields'], new FormFieldFactory());
$fields->validateOn($_POST)
foreach ($fields->getInvalidFields() as $field) {
$messages[] = $field->getErrorMessage();
}
var_dump($messages);
Exemplary output:
array(1) {
[0]=>
string(27) "Cannot validate emailadress"
}
Try this instead :
public function check()
{
foreach ($this->arraykeys as $i => $value)
{
switch ($value)
{
case 'email' :
$checkmail = new checkEmail($_POST);
$checkmail->chkEmail($_POST['email']);
if ($checkmail->chkEmail($_POST['email']) == false)
{
$this->message[] = 'Cannot validate emailadres';
}
break;
}
}
print_r($this->message);
}
Also be sure your property is set to public.
Are you sure $checkmail->chkEmail() is getting false and is working well ?
i want to store Student Object to array. and i try to do with below code. but it always show array count as 0
class Student
{
$StudID = 0;
$Name = null;
}
class Students
{
static private $StudentData = array();
static public function AddNewStudent($id,$name)
{
echo("AuctionID :".$AuctionID."<br/>");
try{
$objstd = new Student();
$objstd->StuID = $id;
$objstd->Name = &name;
array_push($StudentData, $objstd);
}
catch (Exception $e)
{
echo("Error".$e->getMessage());
}
}
static public function TotalStudent()
{
return count($StudentData);
}
}
Students::AddNewStudent(1,"name");
Students::AddNewStudent(2,"name2");
Students::AddNewStudent(3,"name3");
echo('Total auction running : '.Students::TotalStudent().'<br/>');
when i try to show array count it shows 0. i want to store all student data in static list
or then after when ever i want to see the list i get the list from static class only...
Because you're creating a new array instead of referencing the one you declared. Use the self keyword to reference your static object property:
class Students
{
static private $StudentData = array();
static public function AddNewStudent($id,$name)
{
echo("AuctionID :".$AuctionID."<br/>");
try{
$objstd = new Student();
$objstd->StuID = $id;
$objstd->Name = &name;
array_push(self::$StudentData, $objstd);
}
catch (Exception $e)
{
echo("Error".$e->getMessage());
}
}
static public function TotalStudent()
{
return count(self::$StudentData);
}
}
In php you have to prefix static variables with self::, like this:
array_push(self::$StudentData, $objstd);
// and in count:
return count(self::$StudentData);
Why that complicated? Your Student class should take care of it's own, same for Students. Example:
$students = new Students();
$students[] = new Student(1, "name");
$students[] = new Student(2, "name2");
$students[] = new Student(3, "name3");
printf('Total auction running : %d.', count($students));
Example output:
Total auction running : 3.
The classes:
class Student
{
/**
* #var int
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #param int $id
* #param string $name
*/
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
}
class Students extends ArrayObject
{
public function __construct()
{
parent::__construct(array());
}
public function offsetSet($index, $newval) {
if (!($newval instanceof Student)) {
throw new InvalidArgumentException('You can only add values of type Student.');
}
parent::offsetSet($index, $newval);
}
}
I have a structure representing a form and I want to iterate it using RecursiveIterator.
The problem is this only returns the top-level questions. What am I doing wrong?
Whole form:
class Form implements RecursiveIterator{
private $id;
private $caption;
private $other_text;
private $questions = array();
private $current;
private function __construct(DibiRow $row){
$this->id = $row->id;
$this->caption = $row->caption;
$this->other_text = $row->other_text;
$this->loadQuestions();
}
private function loadQuestions(){
$questions = dibi::query('SELECT * FROM cyp_questions WHERE form_id = %i AND parent_id IS NULL', $this->id);
while($question = $questions->fetch()) $this->questions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1);
}
/**
* #throws InvalidArgumentException
* #param $id
* #return Form
*/
public static function loadById($id){
$form = dibi::query('SELECT * FROM cyp_forms WHERE id = %i', $id)->fetch();
if($form === false) throw new InvalidArgumentException('Form with id '.$id.' was not found.');
return new Form($form);
}
/**
* #throws FormFieldException
* #return bool
*/
public function validate($postfields){
}
public function getQuestions(){
return $this->questions;
}
public function getChildren(){
return $this->questions[$this->current];
}
public function hasChildren(){
return count($this->questions) > 0;
}
public function current(){
return $this->questions[$this->current];
}
public function key(){
return $this->current;
}
public function next(){
$this->current++;
}
public function rewind(){
$this->current = 0;
}
public function valid(){
return isset($this->questions[$this->current]);
}
}
Question:
class Question implements RecursiveIterator{
private $id;
private $type;
private $answers = array();
private $subquestions = array();
private $other_text;
private $triggers_unique;
private $caption;
private $current = 0;
public function __construct($id, $type, $caption, $other_text = null, $triggers_unique = false){
$this->id = $id;
$this->type = $type;
$this->caption = $caption;
$this->other_text = $other_text;
$this->triggers_unique = $triggers_unique;
$this->setSubQuestions();
}
private function setSubQuestions(){
$questions = dibi::query('SELECT * FROM cyp_questions WHERE parent_id = %i', $this->id);
while($question = $questions->fetch()) $this->subquestions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1);
}
public function getOtherText(){
return $this->other_text;
}
public function getCaption(){
return $this->caption;
}
public function addAnswer($answer){
$this->answers[] = $answer;
}
public function getChildren(){
return $this->subquestions[$this->current];
}
public function hasChildren(){
return count($this->subquestions) > 0;
}
public function current(){
return $this->subquestions[$this->current];
}
public function key(){
return $this->id;
}
public function next(){
++$this->current;
}
public function rewind(){
$this->current = 0;
}
public function valid(){
return isset($this->subquestions[$this->current]);
}
public function getAnswers(){
return $this->answers;
}
}
Iteration:
$form = Form::loadById(1);
foreach($form as $question){
echo $question->getCaption().'<br />';
}
To iterate over a RecursiveIterator, you have to wrap it into a RecursiveIteratorIterator.
See some examples at
Introduction to Spl
SplWiki
The default iteration mode is only to list leaves. If you also want the containing nodes to appear in the iteration, pass RecursiveIteratorIterator::SELF_FIRST as the second argument to the constructor of the RecursiveIteratorIterator
Well, as you can see here
public RecursiveIterator RecursiveIterator::getChildren ( void )
Returns an iterator for the current iterator entry.
the method should return an object implementing the iterator. Your method return a simple array.
My guess would be to return something like:
public function getChildren(){
return new Question($this->subquestions);
}
This is because you're using a RECURSIVE iterator so it's expected to have each node of the tree of the same type (an iterator)