• Как организовать ограничение для записи по внешнему ключу?

    @NevermindWano
    PHP Разработчик
    Вы пропустили поле name с конкретными моделями в processor_manufacture. Intel засунем в manufacture, если правильно понял, а куда положим конкретный проц? I5, I9 и тд.?
    Но я бы сделал вот такую схему:

    spoiler
    63a3140934c9c696438881.png


    Все таки не лучшая идея под каждый тип товара создавать свою таблицу. Тип товара (проц, ssd, и тд )укажем в таблице type_manufacture. Схема очень упрощенная, просто для примера.
    Ответ написан
  • Что нужно исправить чтобы все работало?

    @NevermindWano
    PHP Разработчик
    Приветствую. Я так понимаю, что это какая-то учебная задачка. По коду видно, что Вы новичок и вам тяжело все это дается, понимаю. Ничего страшного. Все через это проходили.
    Сделать, чтобы всё работало у меня не получилось, но и я не прям углубился в код, но вот, что по быстрому обнаружил:
    <?php
    namespace Test3;
    
    class newBase
    {
    	static private $count = 0;
    	static private $arSetName = [];
    	/**
    	 * @param string $name
    	 */
    	function __construct(int $name = 0)
    	{
    		if (empty($name)) {
    			while (array_search(self::$count, self::$arSetName) != false) {
    				++self::$count;
    			}
    			$name = self::$count;
    		}
    		$this->name = $name;
    		self::$arSetName[] = $this->name;
    	}
    	private $name;   // Для наглядности желательно не перемешивать методы и поля. Лучше когда сначала поля, потом методы.
    	/**
    	 * @return string
    	 */
    	public function getName(): string
    	{
    		return '*' . $this->name  . '*';
    	}
    	protected $value;
    	/**
    	 * @param mixed $value
    	 */
    	public function setValue($value)
    	{
    		$this->value = $value;
    	}
    	/**
    	 * @return string
    	 */
    	public function getSize()
    	{
    		$size = strlen(serialize($this->value));
    		return strlen($size) + $size;
    	}
    	public function __sleep()
    	{
    		return ['value'];
    	}
    	/**
    	 * @return string
    	 */
    	public function getSave(): string
    	{
    		$value = serialize($value); // Здесь ошибка, должно быть $this->value в аргументе serialize()
    		return $this->name . ':' . sizeof($value) . ':' . $value; // Вместо sizeof, должно быть strlen, т.к. $value - строка
    	}
    	/**
    	 * @return newBase
    	 */
    	static public function load(string $value): newBase
    	{
    		$arValue = explode(':', $value);
    		return (new newBase($arValue[0]))
    			->setValue(unserialize(substr($value, strlen($arValue[0]) + 1
    				+ strlen($arValue[1]) + 1), $arValue[1])); // метод setValue ничего не возвращает.
    														   // Предполагается, что он должен вернуть объект класса newBase
    									
    	}
    }
    class newView extends newBase
    {
    	private $type = null;
    	private $size = 0;
    	private $property = null;
    	/**
    	 * @param mixed $value
    	 */
    	public function setValue($value)
    	{
    		parent::setValue($value);
    		$this->setType();
    		$this->setSize();
    	}
    	public function setProperty($value)
    	{
    		$this->property = $value;
    		return $this;
    	}
    	private function setType()
    	{
    		$this->type = gettype($this->value);
    	}
    	private function setSize()
    	{
    		if (is_subclass_of($this->value, "Test3\newView")) { // Ошибка, условие никогда не сработает, т.к. символ \n означает новую строку
    			$this->size = parent::getSize() + 1 + strlen($this->property);
    		} elseif ($this->type == 'test') {
    			$this->size = parent::getSize();
    		} else {
    			$this->size = strlen($this->value);
    		}
    	}
    	/**
    	 * @return string
    	 */
    	public function __sleep()
    	{
    		return ['property'];
    	}
    	/**
    	 * @return string
    	 */
    	public function getName(): string
    	{
    		if (empty($this->name)) {  // Поле name в родительском классе с модификатором private, по-этому ошибка
    			throw new Exception('The object doesn\'t have name'); // Не импортирован класс Exception (use Exception)
    		}
    		return '"' . $this->name  . '": ';
    	}
    	/**
    	 * @return string
    	 */
    	public function getType(): string
    	{
    		return ' type ' . $this->type  . ';';
    	}
    	/**
    	 * @return string
    	 */
    	public function getSize(): string
    	{
    		return ' size ' . $this->size . ';';
    	}
    	public function getInfo()
    	{
    		try {
    			echo $this->getName()
    				. $this->getType()
    				. $this->getSize()
    				. "\r\n";
    		} catch (Exception $exc) {
    			echo 'Error: ' . $exc->getMessage();
    		}
    	}
    	/**
    	 * @return string
    	 */
    	public function getSave(): string
    	{
    		if ($this->type == 'test') {
    			$this->value = $this->value->getSave(); // Здесь иногда прилетает вместо объекта сериализованная строка.
    		}
    		return parent::getSave() . serialize($this->property);
    	}
    	/**
    	 * @return newView
    	 */
    	static public function load(string $value): newBase
    	{
    		$arValue = explode(':', $value);
    		return (new newBase($arValue[0]))
    			->setValue(unserialize(substr($value, strlen($arValue[0]) + 1
    				+ strlen($arValue[1]) + 1), $arValue[1]))
    			->setProperty(unserialize(substr($value, strlen($arValue[0]) + 1
    				+ strlen($arValue[1]) + 1 + $arValue[1]))); // метод setValue ничего не возвращает.
    															// Предполагается, что он должен вернуть объект класса newBase
    				// Также ошибка, в аргументе setProperty - unserialize
    				// Или я не понял задумку. Вторым аргументом unserialize идет options, и тут явная ошибка
    				// https://www.php.net/manual/ru/function.unserialize.php
    
    				// Еще у класса newBase нет метода setProperty
    	}
    }
    function gettype($value): string
    {
    	if (is_object($value)) {
    		$type = get_class($value);
    		do {
    
    			if (strpos($type, "Test3\newBase") !== false) { // Ошибка, условие никогда не сработает, т.к. символ \n означает новую строку
    						                                           // А еще лучше - if ($value instanceof newBase)
    				return 'test';
    			}
    		} while ($type = get_parent_class($type)); // Не совсем понятно, зачем тут нужен этот цикл, что он делает?
    	}
    	return gettype($value); // Если $value не объект - то бесконечная рекурсия???
    }
    
    
    $obj = new newBase('12345'); // Ну про тип аргумента конструктора уже говорили.
    $obj->setValue('text');
    
    $obj2 = new \Test3\newView('O9876');
    $obj2->setValue($obj);
    $obj2->setProperty('field');
    $obj2->getInfo();
    
    $save = $obj2->getSave();
    
    $obj3 = newView::load($save);
    
    var_dump($obj2->getSave() == $obj3->getSave()); // Внутри метода getSave() всегда срабатывает проверка на тип == test,
    												// и внутри этого if вызывается метод getSave() со строки.
    												// нипанятна))))	
    
    /**
    *
    * В целом не совсем понятно, что и как должно работать
    * Я не сильно в код углубился, и не совсем понял задумку,
    * но в целом код не рабочий))).
    *
    */


    Да, и если Вы сформулируете какая стояла задача, то могу помочь написать адекватный код))).
    Ответ написан
    Комментировать