Warning: Missing Argument 1 - php

I am having some problems with my php code: All information returns but I cannot figure out why I am getting the error. For my index page I only inluded the line of code that is actually using that class there really is no other code other than some includes. Im sure it is how I built my __contstruct but i am not sure of the approriate way of doing it. I am missing something in how it is being called from the index page.
This line of code for my __construct works w/o error but I do not want the variable assigned in my class.
public function __construct(){
$this->user_id = '235454';
$this->user_type = 'Full Time Employee';
}
This is my Class
<?php
class User
{
protected $user_id;
protected $user_type;
protected $name;
public $first_name;
public $last_name;
public $email_address;
public function __construct($user_id){
$this->user_id = $user_id;
$this->user_type = 'Full Time Employee';
}
public function __set($name, $value){
$this->$name = $value;
}
public function __get($name){
return $this->$name;
}
public function __destroy(){
}
}
?>
This is my code from my index page:
<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$employee_id = new User(2365);
$employee_type = new User();
echo 'Your employee ID is ' . '"' .$employee_id->user_id. '"' . ' your employement status is a n ' . '"' .$employee_type->user_type. '"';
echo '<br/>';
?>

The problem is:
$employee_type = new User();
the constructor expect one argument, but you send nothing.
Change
public function __construct($user_id) {
to
public function __construct($user_id = '') {
See the outputs
$employee_id = new User(2365);
echo $employee_id->user_id; // Output: 2365
echo $employee_id->user_type; // Output: Full Time Employee
$employee_type = new User();
echo $employee_type->user_id; // Output nothing
echo $employee_type->user_type; // Output: Full Time Employee
If you have one user, you can do this:
$employer = new User(2365);
$employer->user_type = 'A user type';
echo 'Your employee ID is "' . $employer->user_id . '" your employement status is "' . $employer->user_type . '"';
Which output:
Your employee ID is "2365" your employement status is "A user type"

I'm no PHP expert, but it looks like you are creating 2 new instances of class user, and on the second instatiation, you are not passing the user_id into the constructor:
$employee_id = new User(2365);
This, it would seem to me, is creating a new instance of User and assigning this instance to the variable $employee_id - I don't think this is what you want though?
$employee_type = new User();
This looks like you're instantiating another instance of User and assigning it to variable $employee_type - but you have called the constructor User() without passing in an ID as is required - hence the error (missing argument).
The reason your return script contents look OK is because the first instance of the User class has an ID (because you passed it in) and the second one has an employee type because this is set in the constructor.
Like I say, I don't know PHP but I'm guessing you want something more along the lines of:
$new_user = new User(2365);
echo 'Your employee ID is ' . '"' .$new_user->user_id. '"' . ' your employement status is a n ' . '"' .$new_user->employee_type. '"';
Here, you are instantiating a single instance of your user class assigned to the variable $new_user, and then accessing the properties of that single instance.
EDIT: .....Aaaaaaaaand - I was too slow :-)

Related

Laravel: "override" request object?

I have a function where I save a group. I want to "access" it from the page (when the user makes a new group with a form) and from a controller, too (when a process makes a new group, for example when I create a new tenant)
My code is so far:
.
.
.
$this->saveGroup($tenantId, 'Default group');
.
.
.
public function saveGroup(Request $request, $tenantId = 0, $nameFromFunction = ''){
if(!empty($request)){
$name = $request -> name;
} elseif($nameFromFunction != ''){
$name = $nameFromFunction;
} else {
$name = '';
}
if($tenantId > 0 && $name != ''){
$group = new ConversationGroup;
$group -> group_name = $name;
$group -> tenant_id = $tenantId;
$group->save();
}
if($nameFromFunction != ''){
return $group -> id; //if a function calls it
} else {
return redirect("/{$tenantId}/groups"); //if the new group was made from the page
}
}
If I test it with the page's group creation form it works fine, but when I run it from the controller I got the following error:
GroupController::saveGroup() must be an instance of Illuminate\Http\Request, integer given
What I must change if I want to earn this logic?
you could use global request() helper and completely avoid passing Request object to your function, like:
public function saveGroup($tenantId = 0, $nameFromFunction = ''){
//get input named 'name' or default to $nameFromFunction
$name = request('name', $nameFromFunction);
...
The reason this is happening, is because in your function definition, first parameter is not $tenantId, but the object of class request.
So you have to pass an object of request class as a first parameter to get this working.
You should try this way,
public function otherFunction()
{
$this->saveGroup(new Request(['name' => 'Default Group']), $tenantID);
OR
$this->saveGroup(new Request(), $tenantID, "Default Group");
}
public function saveGroup(Request $request, $id = 0, $nameFromFunction = '')
{
echo 'here-your-code';
}

Why is include('../myscript.php') causing an error?

I've been trying to debug my PHP script and I've narrowed down the problem to the line
include "../classes.php";
at the top of my file team_manager.php which is where you see it below.
themes
my_theme
js
management
team_manager.php
project_manager.php
classes.php
footer.php
functions.php
Am I not doing the path correctly? Or could it be something wrong with the contents of classes.php? If it could be a problem with the file being included, below is the file, and let me know if anything immediately stands out as wrong.
<?php
final class MySqlInfo
{
const DBNAME = 'somedb';
const USER = 'someuser';
const PSSWD = 'somepassword';
const TEAMTABLENAME = 'sometablename';
public function getUser ( )
{
return self::USER;
}
public function getPassword ( )
{
return self::PSSWD;
}
}
final class MethodResult
{
public $succeeded;
public $message;
public MethodResult ( $succeededInit = NULL, $messageInit = NULL )
{
this->$succeeded = $succeededInit;
this->$message = $messageInit;
}
}
final class MySite
{
const ROOTURL = 'http://asite.com/subsite';
function getRootUrl()
{
return self::ROOTURL;
}
}
final class TeamManager
{
private $dbcon;
public function TeamManager ( )
{
$dbcon = mysqli_connect('localhost', MySqlInfo.getUser(), MySqlInfo::getPassword());
$dbcon->select_db(MySqlInfo::DBNAME);
// need to add error handling here
}
final public class TeamMember
{
public $name; // team member name
public $title; // team member title
public $bio; // team member bio
public $sord; // team member sort order
public $picfn; // team member profile picture file name
}
public function addMember ( TeamMember $M )
{
if ($this->$dbcon->connect_error)
{
return new MethodResult(false, 'Not connected to database');
}
$q = "INSERT INTO " . MySqlInfo::TEAMTABLENAME . " (" . implode( ',' array($M->name, $M->title, $M->bio, $M->sord, $M->picfn) ) . ") VALUES ('" . implode('\',\'', array($_POST['fullname'], $_POST['title'], $_POST['bio'], $_POST['sord'], $targetFileName)) . "')";
// ^ query for inserting member M to the database
if (!mysqli_query(this->$dbcon, $q))
{
return new MethodResult(false, 'Query to insert new team member failed');
}
return new MethodResult(true, 'Successfully added new member' . $M->name);
}
}
?>
include() might cause an error in case it can't find a file to be included. It's that simple. So you have to make sure that file exists before you include it. Also, never use relative paths like ../script.php, as they introduce a number of issues. And one major issue is that, some hosting providers don't allow relative paths due to security reasons.
So to make sure the file can be included, simply do the check for its existence:
<?php
// dirname(__FILE__) returns an absolute path of the current script
// which is being executed
$file = dirname(__FILE__) . '/script.php';
if (is_file($file)) {
include($file);
} else {
echo 'File does not exist';
}
Also, I see that you write code as an old-school. You might want to take a look at PSR-FIG standards.

Bind outside variable and in Class protected field with method param

How to implement this kind of functionality:
Fill entity eg. Member with data
Bind Member to form with $form->bind($member) to private property _formData
Afterward do some stuff inside $form, eg. $form->validate() with _formData
$member should be also changed as _formData is changed.
class Form {
private $_formData;
function bind1(&$row) {
// this change member outside
$row['full_name'] =
$row['first_name']
. ' ' .
$row['last_name'];
}
function bind2(&$row) {
$this->_formData = $row;
// this will not change memeber
$this->_formData['full_name'] =
$this->_formData['first_name']
. ' '
. $this->_formData['last_name'];
}
}
$member = array('full_name' => null, 'first_name'=>'Fn', 'last_name' => 'Ln');
$form = new Form();
$form->bind1($member);
var_dump($member['full_name']);
// output: 'FnLn'
$form->bind2($member);
var_dump($member['full_name']);
// output: null
Method validate work with private _fieldData, so this to work bind2 test should work.
What you are trying to do is possible, but you need to set a reference of the reference in the bind1 and bind2 method, like this:
$this->_formData = & $row;
You are also making misspellings between full_name and fullName as array keys. For example in the bind2 method:
$this->_formData['full_name'] = $this->_formData['first_name'] . ' ' . $this->_formData['last_name'];
And in your test-code you var_dump full_name. Chaging full_name in bind2 to fullName should fix your issue.
the problem is you are assigning the full_name key of your member variable and trying to access fullName variable so it is returning NULL

OOP with sessions

Let's say I have a class called product which has 2 properties, pid and quantity.
Now, I want to make a session that will hold an array of this class. Code example:
<?php
public class product{
public $quantity;
public $pid;
public function __construct($pid,$qty){
$this->$pid = $pid;
$this->$quantity = $qty;
}
// some methods ....
}
session_start();
$_SESSION['products'][] = new product(103,10);
$_SESSION['products'][] = new product(87,6);
?>
Few questions about this:
Is my way of declaring the sessions is correct? I haven't typed something like $_SESSION['product'] = new array(); I already added objects to it.
When I will want to read the session product, will I have to import the class product to the page in order to read it and get an access to the quantity and the pid properties?
Code example:
session_start();
echo $_SESSION['products'][0]->$pid; // should echo "103" (according the the code exmaple above)
// OR I will have to do it like this:
require_once 'product.inc.php';
session_start();
echo $_SESSION['products'][0]->$pid; // should echo "103"
3.when I access a public property, do I have to access it like this: $this->$prop_name OR $this -> prop_name (difference is with the $ sign)
if you define a variable like $var = array(); it will wipe the previous array.
sessions are available throughout your domain/sub-domain, so as long as you have called session_start() before you access the session variable you're covered.
when you say public property are you referring to the class or the method? If you want to access the method inside itself to refer to it like $this->myFunction = $object; if you want to access the method outside itself but inside the class you do it using SELF::$object = new myFunction();
see this: When to use self over $this?
and this: http://php.net/manual/en/language.oop5.php
hope this helps.
Is my way of declaring the sessions is correct?
Yes. Once you have executed the session_start() the $_SESSION array will exist and be populated with data if any has been saved into previously.
When I want to read the session product, will I have to import the class product to the page in order to read it and get an access to the quantity and the pid properties?
Yes, if you have methods you need to have the class declared in order to use them.
There is a better way of dehydrating and rehydrating a class. That is serialize() and unserialize(). It takes care of all the public, protected and private data, and it also stores the class name. It does not save the methods of course.
Here is some sample code using your original example as a start point. You can run it in your browser to see the results
file product.class.php
<?php
class product{
public $quantity;
public $pid;
private $a = 99;
protected $b = 88;
public function __construct($p,$q){
$this->pid = $p;
$this->quantity = $q;
}
public function show() {
echo '<pre>SHOW '. $this->pid . '</pre>';
}
}
?>
file tst99.php
require_once( 'product.class.php' );
session_start();
$p1 = new product(103,10);
$p2 = new product(87,6);
unset( $_SESSION['products'] );
$_SESSION['products'][] = serialize($p1);
$_SESSION['products'][] = serialize($p2);
echo 'Dehydrated class'.PHP_EOL;
echo '<pre>' . print_r( $_SESSION, TRUE ) . '</pre>';
?>
file tst99a.php
<?php
session_start();
require_once('product.class.php');
echo '<pre>' . print_r( $_SESSION, TRUE ) . '</pre>';
echo 'Rehydrated class'.PHP_EOL;
$np1 = unserialize($_SESSION['products'][0]);
$np2 = unserialize($_SESSION['products'][1]);
echo '<pre>' . print_r( $np1, TRUE ) . '</pre>';
echo '<pre>' . print_r( $np2, TRUE ) . '</pre>';
$np1->show();
$np2->show();
Run tst99.php first and then tst99a.php to see that the class gets fully rehydrated.

PHP call to undefined method, but method is defined... (not the same as other 2 similar questions)

I am going through a tutorial to build up a mock Flickr site in PHP. I am getting to the point where we are adding in all the user CRUD. The user class has already been defined and has methods that are being used and work. But once I added the methods for create, update, delete and save it says it can't find any of them... I have tried modifying the methods that do work, and they don't change. So to me it seems like there is a cached version of the user class, because changes in the user.php file aren't being recognized. I have used ctrl+F5 to refresh the cache, but that doesn't change anything...
This is my directory set up
wamp
www
photo_gallery
includes
config.php
constants.php
database.php
database_object.php
functions.php
initialize.php
session.php
user.php
public
admin
index,php
login.php
logout.php
logfile.php
test.php
images
javascript
layouts
stylesheets
index.php
This is my initialize.php file that sets up the directory paths and loads all the files needed
<?php
// Define the core paths
// Define them as absolute paths to make sure that require_once works as expected
//DIRECTORY_SEPARATOR is a php pre-defined constant
// ( \ for Windows, / for Unix)
defined('DS') ? null : define('DS', DIRECTORY_SEPARATOR);
// checks if lib path exists if not defines the site root with the directory specified below
// ***** needs to be updated when switched directories, servers or computers
defined('SITE_ROOT') ? null :
define('SITE_ROOT', DS.'Users'.DS.'Alan D'.DS.'Desktop'.DS.'wamp'.DS.'www'.DS.'photo_gallery');
// Checks if lib path has been defined, if not it defines it using site path above
defined('LIB_PATH') ? null : define('LIB_PATH', SITE_ROOT.DS.'includes');
// first load config
require_once(LIB_PATH.DS.'config.php');
// load basic functions that are available for all other files
require_once(LIB_PATH.DS.'functions.php');
// load core object classes for application
require_once(LIB_PATH.DS.'session.php');
require_once(LIB_PATH.DS.'database.php');
require_once(LIB_PATH.DS.'database_object.php');
// load database-related object classes
require_once(LIB_PATH.DS.'user.php');
?>
This is the user class, it was simpler then this when I was testing, but I continued to follow through the steps to make the methods able to be dropped into my other classes when I create them.
<?php
require_once('database.php');
class User extends DatabaseObject{
protected static $db_fields = array('id', 'user_name', 'password',
'first_name', 'last_name');
protected static $table_name="users";
public $id;
public $user_name;
public $password;
public $first_name;
public $last_name;
public function full_name(){
if(isset($this->first_name) && isset($this->last_name)){
return $this->first_name . " " . $this->last_name;
} else {
return "";
}
}
// authenticates user by checking if there is a row with the
// input user name and password, then returns the object if found
// if not it returns false
public static function authenticate($user_name="", $password=""){
global $database;
$user_name = $database->escape_values($user_name);
$password = $database->escape_values($password);
$sql = "SELECT * FROM users ";
$sql .= "WHERE user_name = '{$user_name}' ";
$sql .= "AND password = '{$password}' ";
$sql .= "LIMIT 1";
$result_array = self::find_by_sql($sql);
return !empty($result_array) ? array_shift($result_array) : false;
}
// checks to see if the given attribute exsits for the current object
private function has_attribute($attribute){
// associative array with all attributes key and value pairs
$object_vars = $this->attributes();
// just check if the key exists and return true or false
return array_key_exists($attribute, $object_vars);
}
// returns a key value hash of the objects variables and values
protected function attributes(){
// get_object_vars returns an associative array with all attributes
// (incl private) as the keys and their current values as value
// return get_object_vars($this);
// this goes through the db fields and populates the hash
$attributes = array();
foreach(self::$db_fields as $field){
if(property_exists($this, $field)){
$attributes[$field] = $this->$field;
}
}
return $attributes;
}
// returns a sanitized (sql escaped) array of all the attributes
protected function sanitized_attributes(){
global $database;
$clean_attributes = array();
// sanitize the values before submitting
// Note: does not alter the actual value of each attribute
foreach($this->attributes() as $key => $value){
$clean_attributes[$key] = $database->escape_value($value);
}
return $clean_attributes;
}
// this function check to see if the record is already there
// and determines whether to create or update.
public function save(){
return isset($this->id) ? $this->update() : $this->create();
}
public function create(){
global $database;
$attributes = $this->sanitized_attributes();
$sql = "INSERT INTO ".self::$table_name." (";
$sql .= join(", ", array_keys($attributes));
$sql .= ") VALUES ('";
$sql .= join("', '", array_values($attributes));
$sql .= "')";
if($database->query($sql)){
$this->id = $database->insert_id();
return true;
} else {
return false;
}
}
public function update(){
global $database;
$attributes = $this->sanitized_attributes();
// set up the key, value string needed for the update statement
foreach ($attributes as $key => $value){
$attribute_pairs[] = "{$key}='{$value}'";
}
$sql = "UPDATE ".self::$table_name." SET ";
$sql .= join(", ", $attribute_pairs);
$sql .= " WHERE id='". $database->escape_value($this->id);
$database->query($sql);
return($database->affected_rows() == 1) ? true : false;
}
public function delete(){
global $database;
$sql = "DELETE FROM ".self::$table_name." ";
$sql .= "WHERE id=". $database->escape_value($this->id);
$sql .= " LIMIT 1";
$database->query($sql);
return($database->affected_rows() == 1) ? true : false;
}
}
?>
In the admin/test.php file it is set up like this
<?php
require_once('../../includes/initialize.php');
if (!$session->is_logged_in()) { redirect_to("login.php"); }
?>
<?php include_layout_template('admin_header.php'); ?>
<?php
$user = new User();
$user->user_name = "jDoe";
$user->password = "pass";
$user->first_name = "Jamie";
$user->last_name = "Doe";
echo $user->full_name();
$user->save();
//$user = User::find_by_id(1);
//$user->password = "pass1";
//$user->update();
?>
<?php include_layout_template('admin_footer.php'); ?>
When I run that page I get the admin header layout to load, the full name is printed on the screen and directly below it says:
Fatal error: Call to undefined method User::save() in C:\wamp\www\photo_gallery\public\admin\test.php on line 17
The same was happening with create and update... but these functions do exist in the user.php file, I even emptied everything out of the methods to makes sure there was no bug in the php code inside of them.
Then I tried the test from the public folder, through public/index.php
<?php
require_once('../includes/initialize.php');
if (!$session->is_logged_in()) { redirect_to("login.php"); }
?>
<?php include_layout_template('admin_header.php'); ?>
<?php
$user = new User();
$user->user_name = "jDoe";
$user->password = "pass";
$user->first_name = "Jamie";
$user->last_name = "Doe";
$user->full_name();
$user->create();
?>
<?php include_layout_template('admin_footer.php'); ?>
But this doesn't even load the admin header layout... and just gives me the same error as the other test file did. I am pretty positive that I am navigating to the correct path based on the directory set up.
For the life of me I cannot understand why/how the user object isn't being updated when I add things to the user class inside user.php. Or how I could use other methods I had previously defined in user, but they don't change when I modify them... Does php do any caching of objects that I am unaware of? I even pulled the user.php out of the includes directory... and everything still runs as explained above...
Any insight would be greatly appreciated. I have been searching around for a while now trying to find someone with a similar issue but I can't find one. Thanks for reading.
It seems in your initialize.php you have an additional directory in the SITE_ROOT definition compared to what you show in your directory structure. Do you still have another copy of this code perhaps in photo_gallery directory that this is actually including files from?
This is where all your includes are pointing to:
/Users/Alan D/Desktop/wamp/www/photo_gallery/includes

Categories