Returning data in PHP returns Null - php

I am storing the returned data from a query in this private $_data variable.
When I use the $ticket->find() function it is returning data.
When I use $ticket->data() it returns null.
Why would this be if they are both returning the same variable? How can I make data() return AND display the data?
<?php
class Ticket {
public $_db,
$_data;
public function __construct($ticket = null) {
$this->_db = DB::getInstance();
}
public function create($fields = array()) {
if(!$this->_db->insert('tickets', $fields)) {
throw new Exception('There was a problem creating a ticket.');
}
}
public function find() {
$data = $this->_db->get('tickets', array('uid', '=', '18'));
$this->_data = $data;
return $this->_data;
}
public function data() {
return $this->_data;
}
}

Related

How to make Laravel Nova like Fields

I wanna create class for making fields, but in Laravel Nova this classes called like Text::make()->placeholder() and etc. This means that methods inside that class is static.
This is my field class:
class Field
{
private $field = [];
public function set($key, $value)
{
$this->field[$key] = $value;
}
public function get()
{
return $this->field;
}
}
class Text
{
private static $field;
public static function make($name)
{
self::$field = new Field;
self::$field->set('#saturn_type', 'string');
self::$field->set('#saturn_key', $name);
self::$field->set('#saturn_field', 'text');
return new Text;
}
public function placeholder($value)
{
self::$field->set('placeholder', $value);
return $this;
}
public function required()
{
self::$field->set('required', true);
return $this;
}
public function translate()
{
self::$field->set('translate', true);
return $this;
}
public function wysiwyg()
{
self::$field->set('wysiwyg', true);
return $this;
}
public function get()
{
return (array) self::$field->get();
}
}
and this is how i call it:
$fields = [
Text::make('name')->placeholder('Full Name'),
Text::make('email')->placeholder('Email'),
Text::make('password')->placeholder('Password'),
]
$lastArray = $fields->map(function ($field) {
return $field->get();
}
);
But when i call get() method for each item in this array to get array, each item returns the last item's name and placeholder because it is static. How can i solve this.
I found the solution. Actually my friend Nijat found ))
class Field
{
private $field = [];
public function set($key, $value)
{
$this->field[$key] = $value;
}
public function get()
{
return $this->field;
}
}
class Text
{
private $field;
public function __construct($name)
{
$this->field = new Field;
$this->field->set('#saturn_type', 'string');
$this->field->set('#saturn_key', $name);
$this->field->set('#saturn_field', 'text');
}
public static function make($name)
{
return new Text($name);
}
public function placeholder($value)
{
$this->field->set('placeholder', $value);
return $this;
}
public function required()
{
$this->field->set('required', true);
return $this;
}
public function translate()
{
$this->field->set('translate', true);
return $this;
}
public function wysiwyg()
{
$this->field->set('wysiwyg', true);
return $this;
}
public function get()
{
return (array) $this->field->get();
}
}
You just have to create constructor then call it in static method.
You can make Text inherit from Field and have a much simpler make method:
class Field
{
public static function make(...$arguments)
{
return new static(...$arguments);
}
// ...
}
This will instantiate the parent class (e.g. Text) and return it, allowing you to keep the chaining. In the methods you can then use $this-> as usual (instead of self::). And move the content of Text::make to the constructor:
class Text extends Field
{
public function __construct($name)
{
$this->set('#saturn_type', 'string');
$this->set('#saturn_key', $name);
$this->set('#saturn_field', 'text');
}
// ...
}

Not getting desired output from PHP class

This is my very first question actually. I am under a learning process of OOP PHP and trying to design my first class for Category. Here is my code
<?php
class category{
public $catid;
public $datacol;
public function __construct($catid=0)
{
$this->catid=0;
$this->datacol=$this->load($catid);
}
public function load($catid)
{
global $conn;
$sql=' select * '
.' FROM tbl_categories'
.' WHERE catid='.$catid;
if (!($res=mysqli_query($conn,$sql)) || !mysqli_num_rows($res)>0)
return false;
$this->datacol = mysqli_fetch_array($res);
$this->catid = $this->datacol['catid'];
return true;
}
public function reload() {
return $this->load($this->getId());
}
/* ------------------> Getter methods <--------------------- */
public function getId() { return $this->catid; }
public function getName() { return $this->datacol['category']; }
public function getOneliner() { return $this->datacol['categoryoneliner']; }
public function getBrief() { return $this->datacol['categorybrief']; }
public function getThumb() { return $this->datacol['timg']; }
public function getImage() { return $this->datacol['limg']; }
public function getParentID() { return $this->datacol['parentcat']; }
public function getPagetitle() { return $this->datacol['catpagetitle']; }
public function getKeywords() { return $this->datacol['catkeywords']; }
public function getMetadesc() { return $this->datacol['categorymetadesc']; }
public function getPriority() { return $this->datacol['priority']; }
public function getRemarks() { return ($this->datacol['remarks']); }
public function getRow() { return $this->datacol; }
}
?>
Now,
When i create its object from other file with a code as below:
$cat=new category(10);
echo var_dump($cat);
echo var_dump($cat->getId());
echo var_dump($cat->getName());
The output gives me the correct catid when called getID(). But Shows NULL for getName() or any other function other than getID().
What am i doing wrong?
Thanks in advance
As #Arnold Gandarillas said, you are overwriting $datacol in the constructor.
Your constructor calls load(), which sets $datacol:
public function load($catid)
{
...
$this->datacol = mysqli_fetch_array($res);
return true;
}
The function then returns true. In the constructor, this true is assigned to $datacol, overwriting the previous value:
public function __construct($catid=0)
{
$this->catid=0;
$this->datacol=$this->load($catid);
}
Change the constructor to something like this:
public function __construct($catid=0)
{
if ($catid > 0)
$this->load($catid);
}
Alright - look closely to your function:
public function load($catid)
{
global $conn;
$sql=' select * '
.' FROM tbl_categories'
.' WHERE catid='.$catid;
if (!($res=mysqli_query($conn,$sql)) || !mysqli_num_rows($res)>0)
return false;
$this->datacol = mysqli_fetch_array($res);
$this->catid = $this->datacol['catid'];
return true;
}
So, you function returns either true of false. And this boolean values is assgined to $this->datacol here:
$this->datacol = $this->load($catid);
As this assignment happens after you did $this->datacol = mysqli_fetch_array($res);, your $this->datacol becomes either true or false, and holds no real data from mysql.
So, one of the solutions can be to remove assignment:
public function __construct($catid=0)
{
$this->catid=0;
$this->load($catid);
}
In this case your $this->datacol is not overwritten.
its simple $this->datacol = $this->load($catid); is not required
you have assigning $this->datacol twice
public function __construct($catid=0)
{
$this->catid=0;
$this->load($catid);
}
public function load($catid)
{
global $conn;
$sql=' select * '
.' FROM tbl_categories'
.' WHERE catid='.$catid;
if (!($res=mysqli_query($conn,$sql)) || !mysqli_num_rows($res)>0)
return false;
$this->datacol = mysqli_fetch_array($res);
$this->catid = $this->datacol['catid'];
return true;
}
please add if anything is missing

Symfony, creating new object slow

I need to write a foreach loop where users get subscribed and inserted into the database using doctrine. My code:
$i=0;
$batchSize=20;
foreach ($members as $member) {
$subscription = new Subscription($company, $user);
$entityManager->persist($subscription);
// debug
$i++;
error_log($i);
if ($i % $batchSize === 0) {
$entityManager->flush();
$entityManager->clear();
}
}
this code is really slow. For about 100 users, this code needs a couple minutes to execute. This should be a lot faster right?
When I delete the object creation (and the setMember, and entityManager lines) this code is executed is less than a second.
What am I doing wrong?
UPDATE: Entity code
I changed some variables because of code secrets. If any code is wrong, it's because of the fast changes I made so I could post my issue here.
class Subscription implements \JsonSerializable
{
protected $id;
protected $company;
protected $user;
private $created_on;
private $blocked;
private $attributes;
public function __construct(Company $company, User $user)
{
$this->company = $company;
$this->user = $user;
$this->created_on = new \DateTime();
$this->blocked = false;
$this->attributes = new AttributeCollection();
$this->setDefaultAttributes();
}
public function jsonSerialize() {
return array(
'id' => $this->id,
'user' => $this->user,
'blocked' => $this->blocked,
'created_on' => $this->created_on->format('Y-m-d H:i:s')
);
}
// due to company secrets variables have been changed to a,b,c,d,e,f
public function setDefaultAttributes()
{
if (null == $this->attributes)
$this->attributes = new AttributeCollection();
$this->attributes->addAttribute(new Attribute('a'));
$this->attributes->addAttribute(new Attribute('b'));
$this->attributes->addAttribute(new Attribute('c'));
$this->attributes->addAttribute(new Attribute('d'));
$this->attributes->addAttribute(new Attribute('e'));
$this->attributes->addAttribute(new Attribute('f'));
}
public function getId()
{
return $this->id;
}
public function setUser(User $user = null)
{
$this->user = $user;
return $this;
}
public function getUser()
{
return $this->user;
}
public function setCompany(Company $company = null)
{
$this->company = $company;
return $this;
}
public function getCompany()
{
return $this->company;
}
public function getCreatedOn()
{
return $this->created_on;
}
public function setBlocked($blocked)
{
$this->blocked = $blocked;
return $this;
}
public function getBlocked()
{
return $this->blocked;
}
public function setAttributes(AttributeCollection $attributes = null)
{
$this->attributes = $attributes;
return $this;
}
public function getAttributes()
{
return $this->attributes;
}
}
AttributeCollection class used in the Subscription class above:
class AttributeCollection
{
protected $id;
protected $attributes;
public function __construct()
{
$this->attributes = new ArrayCollection();
}
public function removeDefaults()
{
foreach ($this->attributes as $attribute)
if ($attribute->isSystemDefault())
$this->removeAttribute($attribute);
}
public function clearDefaults()
{
foreach ($this->attributes as $attribute)
$attribute->setSystemDefault(false);
}
public function getAttributes()
{
return $this->attributes;
}
public function addAttribute(Attribute $attribute)
{
if (!$this->findAttributeByName($attribute->getName()))
$this->attributes[] = $attribute;
}
public function removeAttribute(Attribute $attribute)
{
$this->attributes->removeElement($attribute);
}
public function findAttributeByName($name)
{
foreach ($this->attributes as $attribute)
if ($attribute->getName() == $name)
return $attribute;
return;
}
public function get($name)
{
$attribute = $this->findAttributeByName($name);
if ($attribute)
return $attribute->getValue();
return;
}
public function getAll()
{
return $this->attributes->toArray();
}
}
It turns out that passing those models through the constructor caused the problem.
I changed my code:
class Subscription {
...
public function __construct($Company == null, $member == null) {
...
}
}
and in my foreach loop:
$subscription = new Subscription();
$subscription->setCompany($company);
$subscription->setMember($member);
this way everything runs smooth and as expected. I have no idea why the constructor is slowing everything down. But apparently it did.
It is not optimal to use such small $batchSize for such small entities.
This way of persisting is presented in documentation as an example of how you can optimize your memory and connection loading, not the speed of whole script.
If you remove these checks on $i and $batchSize it will be faster.
foreach ($members as $member) {
$subscription = new Subscription();
$subscription->setMember($member);
$entityManager->persist($subscription);
}
$entityManager->flush();
Also keep in mind that in dev-env you have debug option is set as enabled and all queries to the DB are logged in files. It also waste a time.

Fetch all results with OOP Php

I've been following a tutorial about oop php on youtube. He made a method to fetch only the first result of a query. I tried to grab all results, but I get a warning message : Trying to get property of non-object
Also when I var_dump(); my object holding the result (which I assumed), it returns null.
What am I doing wrong?
This is the full code:
DB class:
class DB {
private $_results;
public function query($sql, $params = array()) {
$this->_error = false;
if ($this->_query = $this->_pdo->prepare($sql)) {
$x = 1;
if (count($params)) {
foreach ($params as $param) {
$this->_query->bindValue($x, $param);
$x++;
}
}
if ($this->_query->execute()) {
$this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
$this->_count = $this->_query->rowCount();
} else {
$this->_error = true;
}
}
return $this;
}
// First result only:
public function first() {
return $this->results()[0];
}
// All results as I thought:
public function first() {
return $this->results();
}
public function results() {
return $this->_results;
}
}
Project Class:
class Project {
private $_db,
$_data;
public function __construct() {
$this->_db = DB::getInstance();
}
public function find($user = null) {
if ($user) {
$data = $this->_db->get('user_project', array('uid', '=', $user));
if ($data->count()) {
$this->_data = $data->all();
return $this->data()->id;
}
}
}
public function data() {
return $this->_data;
}
}
I tried to access it by doing this:
$project = new Project();
var_dump($project->find($user->data()->id)); // $user->data()->id is just the id of a user
Thanks for pointing me the right direction, I've figured it out.
$this->_data = $data->results();
return $this->_data;
Then I had to loop through it. Solved.

How can I implement Method Chaining in PHP 5.x?

I have the following class written for PHP 5.4.x. Should this work as I expect?
class SqlBuilder {
private $dbTable;
private $action;
private $data;
private $clause;
public function toString() {
// $sql = generate sql string
// [...]
return $sql;
}
[...]
public function setClause($clause) {
$this->clause = $clause;
}
public function setDbTable($dbTable) {
$this->dbTable = $dbTable;
}
public function setAction($action) {
$this->action = $action;
}
}
$sql = (new \dbal\SqlBuilder())
->setAction($this->action)
->setClause($this->clause)
->setDbTable($this->dbTable)
->toString();
I am expecting to be able to access all of my setter methods. Instead I see the following error:
Fatal error: Call to a member function toString() on a non-object )
This seems to work:
$builder= new \dbal\SqlBuilder();
$builder->setAction($this->action)
$builder->setClause($this->clause)
$builder->setDbTable($this->dbTable)
$sql = $builder->toString();
But I know that this works as well:
class Foo
{
public $a = "I'm a!";
public $b = "I'm b!";
public $c;
public function getB() {
return $this->b;
}
public function setC($c) {
$this->c = $c;
return $this;
}
public function getC() {
return $this->c;
}
}
print (new Foo)
->setC($_GET["c"])
->getC(); // I'm c!
I've used this style of syntax in Javascript before. Is there a way to make it work in PHP?
What you are asking about is called method chaining. In order for it to work the way you want, each method call needs to return a reference to the object that you are calling. So,
->setAction($this->action)
// needs to return $this; so that
->setClause($this->clause)
// knows what to operate upon and in turn needs to return $this; so that
->setDbTable($this->dbTable)
// can do the same
Try :
public function setClause($clause) {
$this->clause = $clause;
return $this;
}
public function setDbTable($dbTable) {
$this->dbTable = $dbTable;
return $this;
}
public function setAction($action) {
$this->action = $action;
return $this;
}

Categories