PHP OOP INSERT INTO only insert NULL in Database - mysql

I'm trying to add members in my database using OOP, however it only insert NULL values
It works perfectly fine when I'm not using OOP
Here is my PHP code :
$request = $bdd->query('SELECT id_membre, prenom, nom, ville FROM client');
class Membre {
private $_id;
private $_prenom;
private $_nom;
private $_ville;
/*HYDRATATION*/
public function hydrate(array $donnees) {
foreach($donnees as $key => $value) {
$method = 'set'.ucfirst($key);
if (method_exists($this, $method)) {
$this->$method($value);
}
}
}
public function id() { return $this->_id; }
public function prenom() { return $this->_prenom; }
public function nom() { return $this->_nom; }
public function ville() { return $this->_ville; }
public function setId($id) {
$this->_id = $id;
}
public function setPrenom($prenom) {
$this->_prenom = $prenom;
}
public function setNom($nom) {
$this->_nom = $nom;
}
public function setVille($ville) {
$this->_ville = $ville;
}
}
That part seems to be working fine
class MembreManager {
private $_bdd;
public function __construct($bdd){
$this->setBdd($bdd);
}
public function add(Membre $mbr) {
$q = $this->_bdd->prepare("INSERT INTO client(prenom, nom, ville)
VALUES(:prenom, :nom, :ville)");
$q->bindValue(':prenom', $mbr->prenom());
$q->bindValue(':nom', $mbr->nom());
$q->bindValue(':ville', $mbr->ville());
$q->execute();
}
}
$mbr = new Membre([
'nom' => 'Name',
'prenom' => 'Surname',
'ville' => 'City',
]);
$manager = new MembreManager($bdd);
$manager->add($mbr);
while($donnees = $request->fetch()) {
$mbr = new Membre($donnees);
}
Inserting values only seems to work when I manually input string in my Insert Into.

Related

Symfony Serializer: Denormalize (Deserialize) awkward array data

Using symfony/serializer version 4. The data I am getting back JSON from an API that looks like this
{
"name": "Steves Book Shop",
"book_1": "Lord of the Rings",
"book_2": "The Hobbit",
"book_[n]": "there can be any number of books"
}
I want to deserialize into the following models
class BookShop
{
protected $name;
/** #var Book[] */
protected $books;
public function getBooks(): array
{
return $this->books;
}
public function setBooks(array $books)
{
$this->books = $books;
}
public function addBook(Book $book)
{
$this->books[] = $book;
}
// ... other code removed to save space
}
class Book
{
protected $title;
// ... other code removed to save space
}
When using "cleaner" JSON below, everything works as expected and I get a BookShop with and array of Books returned.
{
"name": "Steves Book Shop",
"books": [
{ "title": "Lord of the Rings" },
{ "title": "The Hobbit" }
]
}
What would be a clean way to denormalize the original JSON which instead has the annoying book_1, book_2 etc.
I have been experimenting with a custom denormalizer (DenormalizerInterface) and my solution is looking much more difficult than you would expect.
Here is the solution I ended up with, I am not completely convinced this is the best way, but its working for the moment. Any feedback welcome:
class StrangeDataDenormalizer extends Symfony\Component\Serializer\Normalizer\ObjectNormalizer
{
protected function isStrangeDataInterface(string $type): bool
{
try {
$reflection = new \ReflectionClass($type);
return $reflection->implementsInterface(StrangeDataInterface::class);
} catch (\ReflectionException $e) { // $type is not always a valid class name, might have extract junk like `[]`
return false;
}
}
public function denormalize($data, $class, $format = null, array $context = array())
{
$normalizedData = $this->prepareForDenormalization($data);
$normalizedData = $class::prepareStrangeData($normalizedData);
return parent::denormalize($normalizedData, $class, $format, $context);
}
public function supportsDenormalization($data, $type, $format = null)
{
return $this->isStrangeDataInterface($type);
}
}
interface StrangeDataInterface
{
public static function prepareStrangeData($data): array;
}
class BookShop implements StrangeDataInterface
{
public static function prepareStrangeData($data): array
{
$preparedData = [];
foreach ($data as $key => $value) {
if (preg_match('~^book_[0-9]+$~', $key)) {
$preparedData['books'][] = ['title' => $value];
} else {
$preparedData[$key] = $value;
}
}
return $preparedData;
}
// .... other code hidden
}
function makeSerializer(): Symfony\Component\Serializer\Serializer
{
$extractor = new ReflectionExtractor();
$nameConverter = new CamelCaseToSnakeCaseNameConverter();
$arrayDenormalizer = new ArrayDenormalizer(); // seems to help respect the 'adder' typehints in the model. eg `addEmployee(Employee $employee)`
$strangeDataDenormalizer = new StrangeDataDenormalizer(
null,
$nameConverter,
null,
$extractor
);
$objectNormalizer = new ObjectNormalizer(
null,
$nameConverter,
null,
$extractor
);
$encoder = new JsonEncoder();
$serializer = new Symfony\Component\Serializer\Serializer(
[
$strangeDataDenormalizer,
$objectNormalizer,
$arrayDenormalizer,
],
[$encoder]
);
return $serializer;
}
You should use ArrayCollection for those books - assuming that those are just another entity on your application

Codeigniter Select JSON, Insert JSON

I have very simple users database: user_id, user_name, user_email
My model this:
class Users extends CI_Model {
private $table;
private $table_fields;
private $table_fields_join;
function __construct() {
parent::__construct();
$this->table = 'users';
$this->table_fields = array(
$this->table.'.user_id',
$this->table.'.user_name',
$this->table.'.user_email'
);
$this->table_fields_join = array();
}
function select(){
$this->db->select(implode(', ', array_merge($this->table_fields, $this->table_fields_join)));
$this->db->from($this->table);
$query = $this->db->get();
if($query->num_rows() > 0){
return $query->result();
} else {
return false;
}
}
function insert($data) {
$data = array(
'user_name' => $data['user_name'],
'user_email' => $data['user_email']
);
$this->db->insert($this->table, $data);
}
My controller this:
class Users extends CI_Controller {
function __construct(){
parent::__construct();
$this->load->model('users');
}
public function select(){
$data['query'] = $this->users->select();
$data = json_encode($data['query']);
echo $data;
}
public function insert($json){
$data = json_decode($json);
$this->users->insert($data);
}
}
And this is my routing.php:
$route['default_controller'] = 'Welcome';
$route['users'] = 'users/select';
$route['users/insert/:(any)'] = 'users/insert';
I would like that 127.0.0.1/users/select give json.
Example: [{"user_name":"user1","user_email":"user#user.de"}]
This JSON insert my table: 127.0.0.1/users/insert/[{"user_name":"user1","user_email":"user#user.de"}]
But my code is not working. :-(
You want to return json object in response, so it's required to set json type in response header. As given here
public function select(){
$data['query'] = $this->users->select();
$this->output
->set_content_type('application/json')
->set_output(json_encode($data['query']));
}
It is required to encode part as below for insert part. so you can use this generated url to call your insert.
site_url('usres/insert/'.urlencode('[{"user_name":"user1","user_email":"user#user.de"}]'));
your insert route should be as
$route['users/insert/:(any)'] = 'users/insert/$1';
your insert method should be updated as
public function insert($json){
$json = urldecode($json);
$data = json_decode($json);
$this->users->insert($data);
}
}

My PDO class returns Error on Execution

I finished transitioning to PDO and am modifying my system according to fatal errors that pop up.
ERR: Call to a member function execute() on a non-object in /home/a1933806/public_html/globals/server-bin/php/core.php
LINE: 43
This is my setup with affected line in bold:
class netCore {
private $armor;
private $boot;
private $dbHost = "*****.*******.com";
private $dbNAME = "********";
private $dbPASS = "********";
private $dbUSR = "********";
private $err;
private $state;
public function __construct() {
$bootloadr = "mysql:host=".$this->dbHost.";dbname=".$this->dbNAME.";charset=UTF8";
$opt = array(PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
try {
$this->boot = new PDO($bootloadr, $this->dbUSR, $this->dbPASS, $opt);
} catch(PDOException $e) {
$this->err = "<b>Lebensborn® netCore™ Error:</b> An exception has been raised during Network-to-Database procedures.<br /><b>Message:</b> ".$e->getMessage().".";
}
}
public function bind($param, $value, $type = null) {
if(is_null($type)) {
switch(true) {
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->state->bindValue($param, $value, $type);
}
public function exe() {
return $this->state->execute();
}
public function count() {
return $this->state->rowCount();
}
public function q($q) {
try {
$this->armor = $this->boot->prepare($q);
$this->state = $armor;
} catch(PDOException $e) {
$this->err = "<b>Lebensborn® netCore™ Error:</b> An exception has been raised during Network-to-Database procedures.<br /><b>Message:</b> ".$e->getMessage().".";
}
}
public function set() {
$this->exe();
return $this->state->fetchAll(PDO::FETCH_ASSOC);
}
public function single() {
$this->exe();
return $this->state->fetch(PDO::FETCH_ASSOC);
}
public function transBegin() {
return $this->boot->beginTransaction();
}
public function transCancel() {
return $this->boot->rollBack();
}
public function transEnd() {
return $this->boot->commit();
}
}

dynamic fetch data function

i have made simple database application in zend framework.in that i have made user class and defined different function for database interaction.this function are called from controller class..but i have to declare each time class object for calling the method of user class in each action.how can i declare user class object one time and use in all action method of controller.
here is my controller page
class UserController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
Zend_Session::start();
}
public function indexAction()
{
$title = Zend_Registry::get('title');
$this->view->assign('name', 'Wiwit');
$this->view->assign('title', $title);
}
public function logoutAction()
{
Zend_Session::destroy();
$this->redirect("/user/login");
}
public function registerAction()
{
$this->view->assign('title','Register');
$request = $this->getRequest();
$this->view->assign('action', $request->getBaseURL()."/user/register");
if($request->isPost())
{
$data = array('first_name' => $request->getParam('first_name'),
'last_name' => $request->getParam('last_name'),
'user_name' => $request->getParam('user_name'),
'password' => $request->getParam('password')
);
$user = new Application_Model_User();
$rows_affected=$user->user_insert($data);
$this->redirect("/user/login");
}
}
public function loginAction()
{
if(isset($_SESSION['username']))
{
$this->redirect("/user/home");
}
$this->view->assign('title','Register');
$request = $this->getRequest();
$this->view->assign('action', $request->getBaseURL()."/user/login");
if($request->getParam('msg'))
{
$this->view->msg='username or password is invalid';
}
if($request->isPost())
{
$data = array(
'user_name' => $request->getParam('user_name'),
'password' => $request->getParam('password')
);
$user = new Application_Model_User();
$result=$user->user_login($data);
if(empty($result)){
$this->redirect("/user/login/msg/login failed");
}
else{
$_SESSION['username']=$result->user_name;
$this->redirect("/user/home");
}
}
}
public function homeAction()
{
if(isset($_SESSION['username']))
{
$this->view->title='home';
$request = $this->getRequest();
$user = new Application_Model_User();
$result=$user->user_grid();
$this->view->rows=$result;
}
else
{
$this->redirect("/user/login");
}
}
public function editAction()
{
$request = $this->getRequest();
$id= $request->getParam("id");
$user = new Application_Model_User();
$result=$user->user_edit($id);
$this->view->assign('data',$result);
$this->view->action= $request->getBaseURL()."/user/update";
}
}
and here is my user class
<?php
class Application_Model_User extends Zend_Db_Table
{
public function user_insert($data)
{
global $DB;
$rows_affected = $DB->insert('user', $data);
return $rows_affected;
}
public function user_login($data)
{
$u_name=array_shift($data);
$pass=array_shift($data);
$select = $this->_db->select()
->from('user')
->where("user_name = ?",$u_name)
->where("password = ?",$pass);
$result = $this->getAdapter()->fetchRow($select);
return $result;
}
public function user_grid()
{
global $DB;
$sql = 'SELECT * FROM user';
$stmt = $DB->query($sql);
$result = $stmt->fetchall();
return $result;
}
public function user_edit($data)
{
$select = $this->_db->select()
->from('user')
->where("id = ?",$data);
$result = $this->getAdapter()->fetchRow($select);
$data = (array) $result;
return $data;
}
public function userupdate($data,$id)
{
global $DB;
$rows_affected =$DB->update('user', $data,'id = '.$id);
return $rows_affected;
}
public function userdelete($id)
{
global $DB;
$rows_affected =$DB->delete('user','id = '.$id);
return $rows_affected;
}
}
?>
You can create your user object in the init() method, and store it as a class variable.
public function init()
{
/* Initialize action controller here */
Zend_Session::start();
$this->user = new Application_Model_User();
}
Then it's available in any action method.
public function homeAction()
{
if(isset($_SESSION['username']))
{
$this->view->title='home';
$request = $this->getRequest();
$result = $this->user->user_grid(); // changed
$this->view->rows=$result;
}
else
{
$this->redirect("/user/login");
}
}

Zend - Losing post values in Mapper

I seem to be losing my post data when passing it from my Controller to my Mapper to insert into my DB. I'm new to this and using the Guestbook template but modified it to be adding a "deal". This is what I have:
Controller
public function newAction()
{
$request = $this->getRequest();
$form = new Application_Form_Deal();
if ($this->getRequest()->isPost()) {
if ($form->isValid($request->getPost())) {
$posts = $form->getValues();
//print_r($posts);
$newdeal = new Application_Model_Deal($posts);
$mapper = new Application_Model_DealMapper();
$mapper->save($newdeal);
return $this->_helper->redirector('index');
}
}
$this->view->form = $form;
}
This is my Mapper
public function save(Application_Model_Deal $deal)
{
$data = array(
'dealname' => $deal->getDealName(),
'dealclient' => $deal->getDealClient(),
'dealtelephone' => $deal->getDealTelephone(),
'dealvalue' => $deal->getDealValue(),
'dealdescription' => $deal->getDealDescription(),
'dealcreated' => date('Y-m-d H:i:s'),
'dealmodified' => date('Y-m-d H:i:s'),
);
/*echo "<pre>";
print_r($data);
echo "</pre>";
exit();*/
if (null === ($dealid = $deal->getDealId())) {
unset($data['dealid']);
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('dealid = ?' => $dealid));
}
}
protected $_dealmodified;
protected $_dealcreated;
protected $_dealdescription;
protected $_dealvalue;
protected $_dealtelephone;
protected $_dealclient;
protected $_dealname;
protected $_dealid;
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function __set($name, $value)
{
$method = 'set' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid deal property');
}
$this->$method($value);
}
public function __get($name)
{
$method = 'get' . $name;
if (('mapper' == $name) || !method_exists($this, $method)) {
throw new Exception('Invalid deal property');
}
return $this->$method($value);
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setDealModified($ts)
{
$this->_dealmodified = $ts;
return $this;
}
public function getDealModified()
{
return $this->_dealmodified;
}
public function setDealCreated($ts)
{
$this->_dealcreated = $ts;
return $this;
}
public function getDealCreated()
{
return $this->_dealcreated;
}
public function setDealDescription($text)
{
$this->_dealdescription = (string) $text;
return $this;
}
public function getDealDescription()
{
return $this->_dealdescription;
}
public function setDealValue( $text)
{
$this->_dealvalue = $text;
return $this;
}
public function getDealValue()
{
return $this->_dealvalue;
}
public function setDealTelephone($text)
{
$this->_dealtelephone = $text;
return $this;
}
public function getDealTelephone()
{
return $this->_dealtelephone;
}
public function setDealClient($text)
{
$this->_dealclient = $text;
return $this;
}
public function getDealClient()
{
return $this->_dealclient;
}
public function setDealName($text)
{
$this->_dealname = $text;
return $this;
}
public function getDealName()
{
return $this->_dealname;
}
public function setDealId($dealid)
{
$this->_dealid = (int) $dealid;
return $this;
}
public function getDealId()
{
// $this->_dealid = (int) $value;
return $this->_dealid;
}
I am a complete loss as to why, when I print_r my $data var in the Mapper everything is gone.
Please help!
This looks odd $mapper->save($newdeal, $posts);
your api is save(Application_Model_Deal $deal)
so it should read $mapper->save($newdeal);.
if you really want to get a handle on mappers and models, these three links helped me alot:
http://survivethedeepend.com/
http://phpmaster.com/building-a-domain-model/
http://phpmaster.com/integrating-the-data-mappers/
You are after a specific work flow :
present form
collect from data (the $post)
validate $post data (if(isValid())
get valid and filtered form values ($form->getValues())
instantiate your deal object ($newdeal = new Application_Model_Deal($posts);)
save/update your deal with your mapper
on success redirect
once your deal object is created the $post data has no further value and the deal object is the important thing to think about. Hope this helps a bit.
Ok I think I found it:
your problem revolves around this $method = 'set' . ucfirst($key); this line will try and call $this->setProperty(); your getters and setters are set up camel case so they won't work. The easiest way to fix this is to rename your getters and setters to:
public function setDealmodified($ts)//not camel cased only first letter is capped.
{
$this->_dealmodified = $ts;
return $this;
}
or you have to camel case your array keys.
Your save() method in the mapper does not have a second argument which you used as your $post parameter.
Refactor:
public function save(Application_Model_Deal $deal, array $post)...