I have class UserService which has 2 functions. CreateUser() add user to database and hashPassword() hash password. But now I have a problem with hash password. Show me error password_hash(): Argument #1 ($password) must be of type string, array given. So what could I resolve this problem ?
class UserService
{
public function createUser(RegistrationRequest $request): void
{
$this->hashPassword($request->correctValidate());
User::create($request);
}
private function hashPassword($request)
{
$password = $request['password'] = Hash::make($request);
return $password;
}
}
public function correctValidate()
{
return $this->validated();
}
If you add something like this to the user model, it will do it automatically.
public function setPasswordAttribute($value) {
$this->attributes['password'] = Hash::make($value);
}
The Hash::make function is requiring you to pass string, hence $request in hashPassword should be string also.
There's many ways for you to solve this. As long as you pass string to the Hash::make function you should be golden.
You should learn how to be able to pass data properly. Its pretty much straightforward, if you pass string to a function that function will receive a string.
To answer your problem, this is one solution:
public function createUser(RegistrationRequest $request): void
{
$validated = $request->correctValidate();
$this->hashPassword($validated['password']);
User::create($request);
}
Will this work?
....
private function hashPassword($request)
{
return Hash::make($request->input('password'));
}
....
Related
For studying purposes I was trying to create a GoF Decorator implementation using as example a possibility to convert a text to compressed text or encrypted text.
<?php
interface DataSource {
public function gerar($texto): string;
public function recuperar($texto) : string;
}
class TextoBase implements DataSource {
public function gerar($texto): string {
return $texto;
}
public function recuperar($texto) : string {
return $texto;
}
}
abstract class Decorator implements DataSource {
private DataSource $decorado;
public function __construct(DataSource $decorado) {
$this->decorado = $decorado;
}
public function gerar($texto): string {
return $this->decorado->gerar($texto);
}
public function recuperar($texto) : string {
return $this->decorado->recuperar($texto);
}
}
class CriptoDecorator extends Decorator {
const KEY = 'vDIa5JdknBqfrKOu8d7UpddnBMCH1vza';
const NONCE = 'Ra5LeH7ntW2rvkz3dmqI5Stx';
public function gerar($texto): string {
return $this->encrypt(parent::gerar($texto));
}
public function recuperar($texto): string {
return $this->decrypt(parent::recuperar($texto));
}
public function encrypt($data) {
return sodium_crypto_secretbox($data, self::NONCE, self::KEY);
}
private function decrypt(string $data): string {
return sodium_crypto_secretbox_open($data, self::NONCE, self::KEY);
}
}
class CompressaoDecorator extends Decorator {
const NIVEL_COMPRESSAO = 6;
public function gerar($texto): string {
return $this->comprimir(parent::gerar($texto));
}
public function recuperar($texto): string {
return $this->descomprimir(parent::recuperar($texto));
}
private function comprimir(string $stringData): string {
return gzcompress($stringData, self::NIVEL_COMPRESSAO);
}
private function descomprimir(string $stringData): string {
return gzuncompress($stringData);
}
}
$texto = "olá mundo !";
$decorado = new CompressaoDecorator(new CriptoDecorator(new TextoBase()));
$texto_decorado = $decorado->gerar($texto);
echo PHP_EOL;
echo $decorado->recuperar($texto_decorado);
For some reason I'm got warning:
Warning: gzuncompress(): data error in C:\wamp64\www\curso\designer_patterns\estrutural\decorator\real_life.php on line 93
So, Is there a way to fix this and allow Both Decorators to be stacked and be used to gerar(generate) and recuperar(retrieve) ?
Thanks in advance
You need to unwind in the same order that you setup. If you compress then encrypt, you need to decrypt and then uncompress.
The fast fix for this specific code is to change your recuperar method in CompressaoDecorator
class CompressaoDecorator extends Decorator
{
public function recuperar($texto): string
{
return parent::recuperar($this->descomprimir($texto));
}
}
If you want to solve this in the abstract, I would handle this with a factory instead that can guarantee order. To do that, I don't think the individual objects themselves should concern themselves with parent, the factory should do the job of chaining things.
Edit
Actually, as I think about this more, you don't need the factory, you just need to swap your order for all of your recuperar methods, so this one would change, too:
class CriptoDecorator extends Decorator
{
public function recuperar($texto): string
{
return parent::recuperar($this->decrypt($texto));
}
}
This should allow you to call either encrypt or compress first, and as long as you use the same chain the reverse should work, too.
I have a simple method get_db_password() which can return a string or under some circumstances it could return null, either case should be considered a valid response.
What I am really testing for is that the script doesnt blow up if the getter is called.
How can I write a test/assertion - which either calls get_db_password() and asserts that the script didnt die, or that can test whether the response was either null or a string. e.g something like
$this->assertInternalType( "string || null", $this->config->get_db_password() );
Source code
<?php
class Config {
/** #var string $db_password stored the database password */
private $db_password;
public function __construct() {
$this->db_password = require(PROJ_DIR . "config/productions.php");
}
/** #return string
*/
public function get_db_password() {
return $this->db_password;
}
}
test code
<?php
class ConfigTest extends PHPUnit\Framework\TestCase {
public $config;
public function test_get_db_password_returns_a_string_or_null() {
$this->config = new Config;
// how can I write this test?
$this->assertInternalType('string || null', $this->config->get_db_password());
}
}
I found this as a satisfactory solution
$this->assertTrue(is_string($pass) || $pass === null);
I'm using a Form class for getting the values of a form in static way. Everything is great. But I want to do it dynamically. I want a form class that will do the job for different forms. In display() method I'm getting value of name, email, password, phone etc. I want that when there are more or less value or in another form the Form class do the job for me dynamically. How can i do that?
//This is Register.php
public function display()
{
Form::setname($_POST['name']);
Form::email($_POST['email']);
Form::password($_POST['pass']);
Form::repassword($_POST['rpass']);
Form::phone($_POST['phone']);
list($name,$b,$c,$d,$e)=Form::getall();
}
<?php
//This is Form.php
class Form
{
private $name;
private $email;
private $pass;
private $rpass;
private $phone;
public static function setname($name)
{
$this->name=$name; // Using $this when not in object context
}
public static function email($email)
{
$this->email=$email;
}
public static function password($pass)
{
$this->pass=$pass;
}
public static function repassword($rpass)
{
$this->rpass=$rpass;
}
public static function phone($phone)
{
$this->phone=$phone;
}
public static function getall()
{
$a=$this->name;
$b=$this->email;
$c=$this->pass;
$d=$this->rpass;
$e=$this->phone;
return [$a,$b,$c,$d,$e];
}
}
There are a few things you have to do to get this right. First, avoid statics. Conceptually each form should be represented by it's own object. Second, use magic methods provided by PHP. Those are very powerful and if used properly can allow for some crazy good designs. Third, use array notation with a single name for all your input elements within a single form, for example, for the name of your form elements: use something like: User[email] instead of just email and User[name] instead of just name and so on and so forth.
Keeping these in mind, the form class could be as follows:
class Form{
private $variables = array();
public function __get($name){
$returnValue = null;
if(isset($this->variables[$name])){
$returnValue = $this->variables[$name];
}
return $returnValue;
}
public function __set($name, $value){
$this->variables[$name] = $value;
}
public function getAll(){
return $this->variables;
}
}
This should be enough for the functionality that you require. In addition, you can add a convenience function that I have found very useful. This could be named as a setAttrubites or setAll function. It would be like this:
public function setAll($allData){
foreach($allData as $key => $data){
$this->variables[$key] = $data;
}
}
This will allow you to set all variables in one swoop using a command like this:
$form = new Form();
$form->setAll($_POST['User']);
In order to make this possible, as I mentioned before, all your input elements should be grouped in an array. So the input elements would be like this:
<input type="text" name="User[name]" />
<input type="text" name="User[email]" />
Hope you get the drift...
You can try to add an array of new variables to the class, much like
$dynamic_form_elements = array();
public static function dynamic_element($element, $value) {
$this->dynamic_form_elements[$element] = $value;
}
After that, simply put the $dynamic_form_elements variable to your list for returning in the getAll() method.
return [$a,$b,$c,$d,$e,$dynamic_form_elements];
It's working fine I just needed a setvalue and getvalue method in Form calss .And call it each time for a specific field in display() method.Is it good or there are any better way?
class Form{
private $value;
public function setvalue($value)
{
$this->value=$value;
}
public function getvalue()
{
$a=$this->value;
return $a;
}
}
public function display()
{
$newform=new Form();
$newform->setvalue($_POST['name']);
$name=$newform->getvalue();
$newform->setvalue($_POST['email']);
$b=$newform->getvalue();
$newform->setvalue($_POST['pass']);
$c=$newform->getvalue();
$newform->setvalue($_POST['rpass']);
$d=$newform->getvalue();
$newform->setvalue($_POST['phone']);
$e=$newform->getvalue();
}
I am getting this error and i can't see what i am doing wrong. I have done the same thing with other objects from other classes which are built in the exact same way and i can't see why i am getting this error now.
The code in which i create the object is this one:
$consulta2 = "SELECT * FROM TiposDireccion WHERE Cliente_CIF='$cif' and Direccion_Direccion='$direccion' and Direccion_CP=$cp ";
echo($consulta2."</br>");
if ($resultado2 = $conexion->query($consulta2)){
while($fila2 = $resultado2->fetch_object()){
$tipodireccion78=$fila2->TipoDireccion_Tipo;
//we see here that the select is returning a correct string with a correct value
echo($tipodireccion78);
//we try to instantiate and it fails =(
$unTipoDireccion=TipoDireccion::constructor1($tipodireccion78);
This is the class TipoDireccion:
<?php
class TipoDireccion{
private $tipo;
private $descripcion;
//Construct auxiliar
function __construct() {
}
//Constructor 1 : completo
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
function ponTipo($tipo) {
$this->tipo = $tipo;
}
function devuelveTipo() {
return $this->tipo;
}
function ponDescripcion($descripcion) {
$this->descripcion = $descripcion;
}
function devuelveDescripcion() {
return $this->descripcion;
}
}
?>
Thank you a lot in advance!
Don't know if this is still relevant to you, but in case anyone else comes on here for an answer. The problem is in this function:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->tipo = $tipo;
return $tipoDireccion;
}
Because in the class definition, you define private $tipo; and then you try and assign $tipoDireccion->tipo to what was passed through the function. However, you aren't trying to access that variable through the scope of the class, you are trying to assign it from the 'public' scope as far as the class is concerned.
The fix for this has two options, the first one would be to change private $tipo; to public $tipo;. But that isn't a good solution as you have an assignment function for it.
Instead, use your functions that you made, which would make the function look like:
function constructor1($tipo) {
$tipoDireccion = new TipoDireccion();
$tipoDireccion->ponTipo($tipo);
return $tipoDireccion;
}
That's how you need to access it from the public scope, which you are doing after you initiate a new one.
function constructor1($tipo) {}
should be
static function constructor1($tipo) {}
I tried $this-> but could not assign a value to $first_name and $last_name variable. Without removing static feature of the function and without inserting static feature to variables, how can I echo full_name()? Here is the code :
<?php
class User {
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 "No name!";
}
}
public static function verify() {
$this->first_name = "firstname";
$this->last_name = "last_name";
}
}
$user = new User();
User::verify();
echo $user->full_name()
?>
You can't. Why not make verify a member function and call it like
$user->verify();
Another alternative would be to pass the user into the verify function, like this:
public static function verify( $user ) {
$user->first_name = 'firstname';
$user->last_name = 'last_name';
}
and call like so:
User::verify($user)
You can't really... other then using the singleton pattern, which rather defeats the point of a static function.
The basic idea is that a static function doesn't require an instance, but what you're trying to do does. I'd suggest verifying the data in a non-static setter function, or in the constructor. Or, if needs must, add a public method verify that isn't static.Think about it: statics don't need an instance, so what are you verifying, if there is no instance (and therefore no "$this").