Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.622
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. Com a ajuda do suporte da Bling, finalmente eu consegui exportar a tabela de produtos do MySQL para o servidor da Bling. Eu estava tentando trabalhar com o arquivo Excel xls, mas esse formato é muito antigo, e acredito que o meu Office não conseguiu simular tal tipo de formato. A minha melhor chance foi usar o formato Excel CSV. Não sei como criar um arquivo desse tipo aqui no Office, então eu pedi para a Bling me mandar um arquivo exemplo, e eu trabalhei em cima dele. Só que o arquivo trabalha com dezenas de campos, e a minha tabela só tem meia dúzia de campos. Para resolver isso, eu criei o campo "vazio" varchar(1) default NULL. Eu também criei um novo campo chamado "pvenda", e pedi para o PHP preencher esse campo para mim. Para o MySQL ter a mesma configuração da planilha exemplo, eu criei 12 campos vazios, assim: CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost` SQL SECURITY DEFINER VIEW `vw_produto` AS SELECT `tbprod`.`codprod` AS `codprod`, `tbprod`.`prod` AS `prod`, `tbprod`.`un` AS `un`, `tbprod`.`cf` AS `cf`, `tbprod`.`origem` AS `origem`, `tbprod`.`venda` AS `preço`, `tbprod`.`vazio` AS `vazio`, `tbprod`.`vazio` AS `vazio2`, `tbprod`.`vazio` AS `vazio3`, `tbprod`.`vazio` AS `vazio4`, `tbprod`.`vazio` AS `vazio5`, `tbprod`.`vazio` AS `vazio6`, `tbprod`.`vazio` AS `vazio7`, `tbprod`.`vazio` AS `vazio8`, `tbprod`.`vazio` AS `vazio9`, `tbprod`.`vazio` AS `vazio10`, `tbprod`.`vazio` AS `vazio11`, `tbprod`.`vazio` AS `vazio12`, `tbprod`.`codbar` AS `codbar` FROM `tbprod` WHERE (`tbprod`.`loc` <> 'a24') ORDER BY `tbprod`.`codprod` Usei uma planilha do Excel XLSM para conectar com o vw_produto do MySQL. Eu não lembro como criar o driver ODBC para conectar o Excel para o MySQL, mas ele conseguiu resgatar 2.016 registros. Com um Excel XLSM de um lado e um Excel CSV do outro, tudo o que eu precisei fazer é usar o comando copiar e colar. O problema é que a Bling só aceita 1000 registros de cada vez. Eu uso o Excel há muito tempo, mas só ontem é que eu fui capaz de selecionar 1.000. Eu usei o seletor de células assim "A2:S1000" sem as aspas. Copiei e colei no Excel CSV. Pedi para o Bling importar os dados na forma "atualização/cadastrar novo produto", a Bling disparou um monte de erro e afirmou que só iria importar os dados que são válidos. Depois selecionei as células A1001:S2000, e finalmente A2001:S2016. Tem um outro provedor que me cobrou R$ 520,00 para fazer esse tipo de serviço, mas a vendedora não conseguiu explicar se é possível atualizar o banco de dados. Já a Bling me deixou fazer o teste sem cobrar nada, ainda estou em fase de teste, e eu fiquei contente com a solução deles, o único problema é que o banco de dados fica hospedado no servidor, e nada garante que qualquer pessoa possa olhar para os dados, mas o mais importante é emitir a nota fiscal. Não sei se é possível executar o Bling pelo celular, eu usei um monitor de 30 polegadas, e achei bem difícil enxergar. O meu desafio agora é instalar uma impressora térmica, o SAT Fiscal, uma extensão virtual do roteador num notebook que só tem uma porta USB. O notebook usa a rede WiFi que muita gente reclama que é bastante instável. Estou me esforçando ao máximo para o meu irmão não gastar tanto dinheiro com o sistema de nota fiscal, mas como eu não tenho nenhuma experiência, estou apanhando com o meu método de tentativa e erro.
  2. Frank K Hosaka

    var_dump( )

    O var_dump( ) é a melhor ferramenta que eu encontrei para procurar os meus erros no PHP. O problema é que eu rodo o código tanto no PC como no Hostinger, e o formato não é o mesmo. Perguntei para a Gemini se é possível formatar o var_dump no Hostinger, e ela disse que sim, ela disse para mexer na configuração do PHP do hospedereiro, na configuração do navegador. e cheguei à conclusão de que o melhor é não mexer com nada. Melhor se contentar com o que o PHP do Hostinger e com o Chrome pode fazer. Por outro lado, o comando dd( ) do Laravel é bacana, funciona do mesmo modo no hospedeiro bem como no PC. Melhor que o var_dump( ), o dd( ) exibe o objeto e também pára tudo. Mesmo que você não esteja interessado em framework (eu também não sei o que é isso), o dd( ) do Laravel é impressionante! O var_dump apanha para mostrar um objeto, já o dd( ) mostra centenas de detalhes inimagináveis, e nas várias vezes que usei esse recurso fiquei imaginando se não é possível encapsular todo o banco de dados dentro de uma Collection.
  3. Frank K Hosaka

    Bling

    Bling é um provedor de serviços lá do Rio Grande do Sul, com ele é possível emitir uma nota fiscal. Para usar esse programa em São Paulo é necessário um equipamento chamado SAT, um computador com Windows e uma impressora térmica, um CNPJ e uma Inscrição Estadual, e dinheiro para o Bling deixar usar os seus serviços. O mais em conta é o plano Cobalto, coisa de mais ou menos R$ 60,00 por mês. Se você não tiver nada disso, ainda é possível usar o Bling por 30 dias como teste, mas o CNPJ é o mínimo necessário. Eu peguei da empresa do meu irmão. Até agora, eu consegui criar dois usuários, mas não consegui importar os dados de produtos. Eu não sei que besteira eu fiz, acredito que eu li algo errado. O certo é eu conversar com o suporte técnico, mas morro de vergonha pedir um favor para quem não paguei coisa alguma. Assim, só me restou o velho método científico da tentativa e erro. Já que não consegui importar, eu pensei no contrário. Cadastrei um produto na unha, e depois eu pedi para exportar. Eu pedi para exportar o arquivo no formato Excel xls. No arquivo exportado, eu criei o segundo registro, copiando os mesmos valores dos campos que não sabia como preencher. Na hora de importar, deu tudo certo, o Bling não disparou nenhuma mensagem de erro. Tudo me leva a crer que o formato que eu usei no campo NCM do MySQL não é o mesmo que o Bing esperava; se for isso, vou estudar MySQL ou PHP para consertar o banco de dados. Mas, enfim, eu gostei do marketing da Bling, você experimenta primeiro. Se gostar, comece a pagar. É uma pena que pouca gente faz isso.
  4. Eu fui pegando alguns códigos aqui e outros ali que usavam o rótulo de MVC ou POO, e consegui fazer funcionar o meu projeto. O fato do meu projeto funcionar não implica que eu sei o que é MVC ou POO, muito pelo contrário. Assim eu achei mais justo chamar o meu projeto de POG, Programa Orientado à Gambiarra. Veja o meu drama: Arquivo Index.php <?php class Controle { public function view($arquivo, $array = null) { if (!is_null($array)) { foreach ($array as $var => $value) { ${$var} = $value; } } ob_start(); include $arquivo . ".php"; ob_flush(); } } $teste="meu nome é frank"; (new Controle)->view('visao'); Arquivo visao.php <h1><?=$teste?></h1> Esse programa não funciona, o PHP reclama que a variável $teste não foi definida. Para fazer esse programa funcionar, eu tenho que usar um array, assim: (new controle)->view(visao,['teste'=>$teste]); Desde que comecei a mexer com as classes, eu não consegui entender a lógica. Se eu defini $teste no index.php, por que o visão.php não consegue enxergá-lo? Eu fiquei imaginando que o problema é a função ob_start( ) e o ob_flush( ). Já li umas dezes vezes o manual, e não sei o que ele é e para que serve. Como eu não sei a quem pedir ajuda (a Gemini só repete a mesma coisa que está no manual), o único jeito de resolver o problema é usar o poderoso método científico da tentativa e erro. Eu joguei fora essas funções, e o programa continua funcionando do mesmo jeito. Mas hoje, dia 15 de março de 2024, na hora que comecei a escrever essa mensagem, eu descobri porque o arquivo visão.php não enxerga a variável $teste que eu defini no index.php. É que o arquivo visão não foi chamado pelo arquivo index.php, mas sim por uma classe, e nenhuma classe é obrigada a saber o que o usuário andou definindo antes dela ser chamada.
  5. Achei o erro! Encontrei dois arquivos, um se chama mvc.php e outro se chama MVC.php, ele é ponto de partida do meu projeto que usa as classes do PHP. O correto é usar o index.php, mas esse arquivo está sendo utilizado para dar suporte aos códigos que eu fiz em PHP, tudo no diretório raiz. A confusão começou na semana passada, eu fiquei contente com o roteador do William Duarte, ele resolveu um monte de problemas que enfrentava com as classes, principalmente como passar os parâmetros para a função, nisso, precisei mudar o arquivo mvc.php e todas as classes precisaram se adaptar. O problema é que eu não sabia que criei dois arquivos com nomes semelhantes lá no servidor.
  6. Estou tendo problema no meu projeto Orçamento. Ele funciona aqui no PC, mas não funciona na Hostinger. Olha só a mensagem dele: Fatal error: Uncaught ArgumentCountError: Too few arguments to function ControleDiario::novaData(), 0 passed in /home/astudy-php/htdocs/astudy.net/mvc.php on line 10 and exactly 1 expected in /home/astudy-php/htdocs/astudy.net/Controles/ControleDiario.php:143 Stack trace: #0 /home/astudy-php/htdocs/astudy.net/mvc.php(10): ControleDiario->novaData() #1 {main} thrown in /home/frankhosaka-php/htdocs/php.frankhosaka.net/Controles/ControleDiario.php on line 143 Para tirar a minha dúvida, inventei esse código: Arquivo Index.php <?php class ControleDiario { public function novaData($novaData) { return print_r($novaData); } } if($_GET) { $rota=key($_GET); // roteador de William Duarte $segmentos=explode('_',$rota); $nomeControle=$segmentos[0] ?? 'ControleLogin'; $metodo=$segmentos[1] ?? 'login'; $parametro=$segmentos[2] ?? null; $controle=new $nomeControle(); $controle->$metodo($parametro); } ?> <input type=date value=<?=date('Y-m-d')?> onchange="location.replace('?ControleDiario.novaData.'+this.value)"> Na primeira tentativa, o Hostinger respondeu: 403 Forbidden. Nessa hora, lembrei que o Hostinger trabalha com Linux e o meu PC com Windows, eu tive que renomear o arquivo para index.php. Mas, ele funcionou do mesmo jeito que no PC; esse erro vai ser difícil de achar.
  7. Desde 2020, eu tento montar a função multiplique no JavaScript, e ainda não consegui. A ideia é calcular uma multiplicação tipo 12,5 * 2 dentro de um <input>. Eu tenho o rascunho do projeto, mas ele é bem limitado, ele só funciona se você usar a tecla {TAB}, ele não funciona se você usar a tecla {ENTER}. Arquivo Index.php <script> function ponto(numero) { string=numero.toString() if(string.includes(".")) { return string.replace(".",",") } else { return numero } } function virgula(numero) { string=numero.toString(); if(string.includes(",")) { return string.replace(",",".") } } function multiplique(expressao) { fase=virgula(expressao) partes=fase.split('*'); if(partes.length==1) { return CustoTotal.value=expressao } numero1=parseFloat(partes[0]) numero2=parseFloat(partes[1]) return CustoTotal.value=ponto(numero1*numero2) } </script> <form> Custo Total <input id=CustoTotal onchange=multiplique(this.value)> <br> <input type=submit> </form>
  8. POG é a tentativa de transformar um código PHP em POO através de improvisações, ou mais exatamente, Programa Orientado à Gambiarra.
  9. Não tive sorte com a Gemini e nem com o motor de busca do Google, não consegui achar um código exemplo onde o MVC pega os dados do usuário. Eu mesmo fiz um teste, imaginando que o objeto ficava escondido na memória RAM, e ele iria aparecer na hora que eu precisasse. Foi uma completa besteira. Eu pensei em deletar o projeto, mas eu fiquei imaginando em mudar o esquema. O controle chama o view, mas com o seu nome. E o view devolve o input do usuário mas com o nome do controlador. A gambiarra deu certo, pelo menos no mini projeto que eu fiz, olha só: Arquivo Index.php <?php class candidato { public function __construct() { if(isset($_GET['candidato'])) { echo "o nome do canidato é " . $_GET['candidato']. "<br>"; (new cliente); exit; } $rota="candidato"; return require 'view.php'; } } class cliente { public function __construct() { if(isset($_GET['cliente'])) { echo "o nome do cliente é " . $_GET['cliente']; exit; } $rota="cliente"; return require 'view.php'; } } if($_GET) { $controle=key($_GET); (new $controle); } (new candidato); Arquivo view.php <form> Nome do <?=$rota?> <input name='<?=$rota?>'> <input type=submit> </form>
  10. Agradeço pela sua intervenção, mas você precisa entender que existem apenas dois tipos de pessoas. Tem aquelas que enxergam o mundo em três dimensões, altura, largura e profundidade, é o seu caso. E tem aquelas que vivem dentro de uma linha e não tem a menor ideia qual é o lado da frente e o lado de trás, esse é o meu caso. O POO é abstrato demais para mim, eu fiquei admirado com o seu controlador e auto carregador, mas sou incapaz de depurá-lo. Eu só sei que ele funciona. Eu estou preso no código PHP, cheio de gambiarra difícil de entender e fazer manutenção. Levei dois anos para entender como funciona o auto carregador e o roteador, o máximo que eu consegui fazer é copiar e fazer algumas adaptações. Hoje eu tentei trabalhar com o __construct( ). Foi um grande fiasco. Eu pensei que ele era capaz de enxergar o cabeçote do navegador, mas hoje eu aprendi que ele só funciona se alguém invocar o objeto no cenário. Explicando melhor. Eu pedi para mudar o período de apuração do balancete. Apareceu o HTML com as opções, eu escolhi 01-2024, e pimba! ?apuracao=01-2024 foi lá no cabeçote do navegador. Você sabe o que o balancete fez? Nada, deixou a tela em branco. Eu desconfio que o balancete morreu, eu só perdi tempo ao definir public function __construct( ) { if(isset($_GET['apuração'])){echo "O POG funciona!";}}
  11. Durante muito tempo eu usei o json_decode(json_encode($array)) para obter um objeto literal no PHP. Nessa semana, eu encontrei uma outra forma de obter um objeto no PHP: <?php $programador=(object)['nome'=>'Fabio Akita']; echo "Olá, $programador->nome"; // Olá, Fábio Akita echo "<p>"; $diaDaSemana=(object)['Sun'=>'domingo','Mon'=>'segunda-feira','Tue'=>'terça-feira', 'Wed'=>'quarta-feira', 'Thu'=>'quinta-feira', 'Fri'=>'sexta-feira', 'Sat'=>'sábado']; $day=date("D"); echo "Hoje é " . $diaDaSemana->$day ." (".date('d/m/Y'). ")"; // Hoje é domingo (10/03/2024)
  12. Estudando o meu código POG, eu vi que não é possível abrir mão do verbo extends. No código a seguir, a classe Controle não tem absolutamente nada, isso porque todo o código exemplo está no diretório raiz. Mas na hora que eu colocar a Conexão na pasta Modelos, os controles na pasta Controles, e o HTML na pasta Visões, vou usar a classe Controle para que todos os outros controles estejam dentro de uma sessão e usem todas as funções e constantes que defini no Config.php. Logo, não vejo como viver sem o verbo extends. O que eu aprendi é que não dá para criar um construtor (public function __construct( )) dentro da classe Controle, e isso vai possibilitar o uso dessa ferramenta nos outros controles. A minha ideia é usar o construtor para os outros controles para que eles fiquem atentos no cabeçote do navegador. arquivo Index.php <?php class Conexao { private static $pdo; public static function instancia() { if(!self::$pdo) { self::$pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); } return self::$pdo; } public function select($sql) { $smt=$this->instancia()->query("Select $sql"); return $smt->fetchAll(PDO::FETCH_OBJ); } } class Controle {} class ControleProduto extends Controle { public function listaProduto() { return var_dump((new Conexao)->select("* from tbprod limit 5")); } } (new ControleProduto())->listaProduto();
  13. O código a seguir é de alto nível, eu jamais seria capaz de escrevê-lo. O código original do roteador do William pressupõe que o desenvolvedor vai usar a chave 'rota' para redirecionar o comando para outro canto do código. No HTML, seria mais ou menos assim <form action="?rota=ControleLogin.menu"> ou <a href="?rota=ControleLogin.menu">. Eu alterei para não usar nenhuma chave. Arquivo Index.php <?php ini_set('display_errors', 1); require __DIR__ . '/Modelos/Config.php'; $rota='ControleLogin_login'; if($_GET) { $rota=isset($_GET) ? key($_GET) : $rota; } $segmentos=explode('_',$rota); $nomeControle=$segmentos[0] ?? 'ControleLogin'; $metodo=$segmentos[1] ?? 'login'; $parametro=$segmentos[2] ?? null; $controle=new $nomeControle(); $controle->$metodo($parametro); arquivo Modelos / Config.php <?php date_default_timezone_set('America/Sao_Paulo'); $baseDir = $_SERVER['SERVER_NAME'] === 'astudy.net' ? $_SERVER['DOCUMENT_ROOT'] : $_SERVER['DOCUMENT_ROOT'].'/POO/'; define('PROJETO', $baseDir); define('CONTROLES', PROJETO.'/Controles/'); define('MODELOS', PROJETO.'/Modelos/'); define('VISOES', PROJETO.'/Visoes/'); define('HOST', 'localhost'); define('DBNAME', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Diario' : 'diario'); define('USER', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? 'Root' : 'root'); define('PASSWORD', $baseDir === $_SERVER['DOCUMENT_ROOT'] ? '12345678' : ''); spl_autoload_register(function ($classe) { $diretorios = ['Controles', 'Modelos', 'Visoes']; foreach ($diretorios as $diretorio) { $arquivo = PROJETO . DIRECTORY_SEPARATOR . $diretorio . DIRECTORY_SEPARATOR . $classe . '.php'; if (file_exists($arquivo)) { require_once $arquivo; return; } } throw new Exception("Erro ao carregar a classe '{$classe}'. Arquivo não encontrado."); });
  14. Hoje eu tentei usar a técnica da fatoração ("transformar um código complexo em mais simples") no meu projeto, mas o resultado foi um completo desastre. O resumo do meu projeto é esse: Arquivo Index.php <?php class Controle { public $Conexao; public function __construct() { $this->Conexao=new mysqli("localhost","root","","diario"); } } class ControleProduto extends Controle { public function listaProduto() { return var_dump($this->Conexao->query("select * from tbprod limit 5") ->fetch_all(MYSQLI_ASSOC)); } } $controle=new ControleProduto(); $controle->listaProduto(); Eu tentei criar um construtor na classe ControleProduto, e o PHP retornou Call to a member function query() on null. Foi aí que eu percebi que eu fiz um monte de gambiarra. Ele começa na classe Controle, ninguém usa uma variável pública numa classe. Mas eu usei. Porque essa foi a única maneira que eu encontrei para a classe ControleProduto enxergar a Conexão que foi definida na classe Controle. O segundo erro foi eu tentar criar um public function __construct( ) na classe ControleProduto. Na hora que eu tentei fazer isso, o PHP ficou perdido. Ou seja, o ControleProduto é uma extensão da classe Controle. Como já existe um construtor no Controle, o PHP não tem como se organizar com duas funções com o mesmo nome. Acabei concluindo que eu devo definir a conexão em cada classe que precisar dela e que jamais devo usar o verbo extends, enquanto eu estiver disposto a continuar a fazer gambiarra.
  15. O William Duarte disse que o meu código não é POO, não é PHP, não é Laravel, e sim um POG, um monte de códigos inaproveitáveis. Isso cheira um insulto, mas eu considero como um elogio. Finalmente encontrei alguém que gasta um pouco do seu tempo para apontar os erros nos meus códigos. Ele corrigiu o meu Config.php onde está o autoload, bem como o roteador que deixei no Index.php. Ele usou a anotação $valor = isset($_GET['chave']) ? $_GET['chave'] : null; eu jamais iria usar esse recurso no Config.php se não fosse a intervenção do William Duarte. O meu projeto é só fazer um orçamento, a velha tabuada z = x * y, e eu nunca escondi que não sei nada de informática, não sei o que é memória RAM e memória ROM. Desde 1990 é que tento montar esse projeto, mas em 2020 eu desisti de tentar fazer pelo Visual Basic. Procurei um novo caminho, é o que eu chamo de PHP. Eu fiquei feliz da vida, quando o PHP conseguiu botar o banco de dados no meu celular, ou seja, eu posso fazer a tabuada em tempo real, graças à mágica da internet. Mas eu encontrei várias orientações, afirmando que é necessário estudar HTML, CSS e JavaScript, antes de você começar a usar o PHP, isso o professor Guanabara repetiu várias vezes. Eu não dei ouvidos, e fui pegando um código aqui e um código ali, e colando no projeto frankstein. Eu apanhei muito, principalmente com datepicker do JQuery. Num belo dia, alguém me disse por que eu não uso o <input type="time">, eu fiquei impressionado, ele é muito mais fácil de trabalhar. Joguei fora a biblioteca do JQuery, e comecei a valorizar a biblioteca do HTML, ele é enorme, e lá encontrei o objeto DOM. Nossa, isso não é para mim! De brincadeira, eu baixei o Laravel, eu apanhei um monte para fazer aquilo funcionar. Mas só ontem é que me dei conta de que o Laravel não tem absolutamente nada a ver com o PHP. No PHP, para você transformar um vetor $array num objeto, basta usar o comando json_decode(json_encode($array)); no Laravel, esse comando não funciona. O Laravel usa uma biblioteca diferente, onde usa (object)[$array] para transformar um $array num objeto. Isso é bacana, mas levei três meses para descobrir que esse recurso existe na biblioteca do Laravel. Enfim, qual a maneira certa de estudar o PHP? O certo é ver a biblioteca, mas aquilo é um texto cheio de abstrações do tipo que você encontra no Livro dos Espíritos, onde você não encontra nenhum exemplo prático para saber qual é o espírito benigno ou maligno. Eu desisti, e assim estou caminhando com as minhas improvisações. Ontem, no entanto, eu criei um código bem bacana que me deixou de queixo caído: <?php class escolha { public function __construct() { ?> <a href="?escolha=1">Escolha 1</a><br> <a href="?escolha=2">Escolha 2</a> <?php } } if(isset($_GET['escolha'])) { return print_r("O usuário escolheu a opção " . $_GET['escolha']); } $escolha=new escolha(); Ele é uma tabuada muito diferente que eu criei no PHP em 2020 ou no MVC de 2024. Em 2020, eu usei a memória ROM, quero dizer, o MySQL para gravar a escolha do usuário. Em 2024, eu usei a memório meio-ROM, o PHP chama de variável global, a ferramenta $_SESSION. Mas o código que inventei ontem não usa nada disso, ele só usa a memória RAM, ou seja, o que estiver disponível no cabeçote do navegador. Eu perdi um tempão para saber como a rotina da apuração iria devolver o comando para o controlador que solicitou o serviço, e essa foi uma ótima solução. A rotina que eu criei só vai pegar a escolha do usuário e mais nada. O que o usuário escolheu, isso é problema do controlador que precisa da informação, tudo o que ele tem que fazer é olhar o cabeçote do navegador. Ou seja, na base da tentativa e erro, vou começando a aprender o que é programação orientada à gambiarra. Claro que isso não dá dinheiro e nem futuro, mas isso é um bom passa-tempo quando você não encontra nada interessante no Facebook.
  16. Obrigado, William, eu sabia que o meu código não é um MVC e sim um POG (Programação Orientada a Gambiarra). O núcleo do problema no PHP, MVC e Laravel é a gramática, eu não sei o que é responsabilidade, documentação, fatoração, lógica, autoloader, organização e roteador, enfim estou cansado de receber a mesma orientação, o de que para ser um desenvolvedor preciso estudar, estudar e estudar. Estudar é terrível, dói a minha cabeça. Tudo o que me resta é o velho método científico da tentativa e erro, faço várias tentativas até conseguir o que eu quero, e não o que é o certo. Voltando ao caso da escolha, o meu novo POG ficou assim: <?php class escolha { public function __construct() { ?> <a href="?escolha=1">Escolha 1</a><br> <a href="?escolha=2">Escolha 2</a> <?php } } if(isset($_GET['escolha'])) { return print_r("O usuário escolheu a opção " . $_GET['escolha']); } $escolha=new escolha(); Nesse novo POG, eu consegui ficar livre da variável global $_SESSION, acredito que criei um objeto escolha de verdade. Tudo o que o objeto escolha faz é pegar a escolha do usuário. Quem vai pegar a escolha é o controller que chamou a função. Esse é o lado bacana da POO, o da simplificação, mas a minha prioridade não é transformar o meu POG em POO, e sim como estudar o PHP, o Laravel e o MVC. Ontem, eu fiquei contente ao descobrir que é possível o Laravel trabalhar com json. Ao invés de usar com json_decode(json_encode etc, a nova gramática do Laravel é bem melhor, assim return (object)["chave":"valor"], mas isso descobri pela força do acaso, não encontrei a resposta na Gemini e nem no labirinto de sugestões do Google. Ou seja, não estou preocupado com o paradigma do POO, e sim como fazer o meu POG funcionar para mim. Mas sem dúvida as orientações são valiosas. Espero que você continua a me ajudar.
  17. O código a seguir é o esquema que eu usei para pegar a opção do usuário. É um código horroroso, não dá para documentar, e nem afirmar que eu criei um "objeto" chamado "escolha". Trata-se de uma gambiarra e não um MVC. O problema é que eu não sei onde procurar um código exemplo, onde é possível pegar a opção do usuário. <?php session_start(); class escolha { public function __construct() { if(isset($_GET['escolha'])) { $_SESSION['escolhido']=$_GET['escolha']; return header('location:index.php'); } } public function mostrarEscolha() { ?> <a href="?escolha=1">Escolha 1</a><br> <a href="?escolha=2">Escolha 2</a> <?php } } if(isset($_SESSION['escolhido'])) { echo "a opção escolhida foi: " . $_SESSION['escolhido']; unset($_SESSION['escolhido']); exit; } $escolha=new escolha(); $escolha->mostrarescolha(); ** importante: esse código só funciona no Windows. No sistema Linux não é permitido você chamar a função mostrarEscolha usando tudo minúsculo, tipo mostrarescolha.
  18. Consegui achar a solução! Arquivo app / Helpers.php function apuracao($dia) { $mesVetor=['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho', 'Agosto','Setembro','Outubro','Novembro','Dezembro']; $ano=date('Y',strtotime($dia)); $mes=date('m',strtotime($dia)); $apuracao=$mesVetor[$mes-1] . " de $ano"; $primeiroDia="$ano-$mes-01"; $ultimoDia=date('Y-m-t',strtotime($primeiroDia)); return (object)[ 'apuracao'=>$apuracao, 'primeiroDia'=>$primeiroDia, 'ultimoDia'=>$ultimoDia]; } arquivo app / Http / Controllers / TesteController.php <?php namespace App\Http\Controllers; Class TesteController Extends Controller { public function inicio() { dd(apuracao('2024-03-07')->apuracao); } } Arquivo routes / web.php <?php use Illuminate\Support\Facades\Route; Route::get('teste',[App\Http\Controllers\TesteController::class,'inicio']);
  19. Obrigado, William. O Eloquent é fantástico, mas ele não tem nada a ver com o Model. O Eloquent é uma gramática, e o Model é apenas uma alavanca para dar mais poder de fogo para o Eloquent. Esse não é o meu caso com o MVC. Para quem está começando a estudar o MVC, que é o meu caso, acho melhor só colocar uma conexão e as funções que serão utilizadas na pasta Modelos do MVC. A grande dor de cabeça do MVC são as pastas. Eu só consegui fazer o MVC funcionar depois que eu aprendi a usar o autloader e o roteador. Eles estão aqui: Arquivo Index.php <?php ini_set('display_errors', 1); require __DIR__ . '/Modelos/Config.php'; if($_GET) { $comando=explode('_',key($_GET)); $controle=new $comando[0]; $funcao=$comando[1]; if(count($comando)==3) { $_GET[$funcao]=$comando[2]; } call_user_func(array($controle,$funcao)); } else { $login=new ControleLogin(); $login->login(); } Arquivo Modelos / Config.php <?php date_default_timezone_set('America/Sao_Paulo'); if($_SERVER['SERVER_NAME']=='astudy.net') { defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT']); $dbname="Diario"; $user="Root"; $password="12345678"; } else { defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT'].'/Frank/'); $dbname="diario"; $user="root"; $password=""; } defined('CONTROLES') || define('CONTROLES',PROJETO.'/Controles/'); defined('MODELOS') || define('MODELO',PROJETO.'/Modelos/'); defined('VISOES') || define('VISOES',PROJETO.'/Visoes/'); defined('HOST') || define('HOST','localhost'); defined('DBNAME') || define('DBNAME',$dbname); defined('USER') || define('USER',$user); defined('PASSWORD') || define('PASSWORD',$password); defined('lctoBaixaEstoque') || define('lctoBaixaEstoque',11301); defined('lctoAcertoMais') || define('lctoAcertoMais',11658); defined('lctoAcertoMenos') || define('lctoAcertoMenos',11659); defined('diaAcerto') || define('diaAcerto','2024-03-31'); spl_autoload_register(function($Class) { $includeDir = false; $findDir = ['Controles','Modelos','Visoes']; foreach ($findDir as $DirName) { if (!$includeDir && file_exists(FindClass($DirName, $Class)) && !is_dir(FindClass($DirName, $Class))) { include_once (FindClass($DirName, $Class)); $includeDir = true; } } if (!$includeDir) { die(FindClass($DirName,$Class)."- Erro interno no servidor ao encontrar dados cruciais de funcionamento!"); } }); function FindClass($dir, $class) { if($_SERVER['SERVER_NAME']=="astudy.net") { return ( $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $class . '.php'); } else { return ( $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'frank' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $class . '.php'); } } Eu alterei o código do roteador . O autor original usava a sintaxe <a href=?cotroller=ControleDiario.method=diario>, eu fiz uma bela gambiarra e consegui fazer a mesma coisa com a sintaxe <a href=?ControleDiario.diario>. O meu código é bem obscuro, mas muito mais obscuro é o arquivo web.php do Routes do Laravel. Depois que consegui resolver o problema da navegação dentro do MVC, outro grande problema é como usar o método de uma classe a partir de vários métodos diferentes em classes diferentes. A minha ideia é transformar o método bastante solicitado numa função. O problema é que o método está amarrado num arquivo HTML, ou seja, eu não consegui montar uma função PHP com um HTML embutido. Lá em 2020, eu usei uma tabela auxiliar no MySQL no código PHP. No MVC de 2024, usei a variável global SESSION bem como as definições de constantes, e o algoritmo ficou assim: Balancete chama Apuração, assim <a href="?ControleDiario.apuracao.balancete"> A apuração guarda o endereço de quem chamou $_SESSION['endereco']=$_GET['apuracao'] e depois chama facaAEscolha.html, o usuário faz a escolha, o HTML devolve a apuração escolhida para a apuracao, assim: <a href="?ControleDiario.apuracao.<?=$período ?>"><?=$periodo?></a>, e finalmente a função apuração salva o valor escolhido na SESSION['apuracao'], e finalmente termina a rotina com um header("location:?".$_SESSION['endereco']. É uma baderna! Não há como tornar o código legível, mas isso é o máximo que eu consegui com o meu método científico da tentativa e erro. Enfim, o MVC é bacana, mas ainda não peguei o jeito do conceito de 'objeto'. Por enquanto, ele é apenas uma variável que morre assim que o usuário aperta a tecla enviar. Para não perder tudo no caminho, eu salvei alguns valores no SESSION, e espero utilizar o recurso do SESSION no arquivo Conexão para me informar exatamente aonde começou o problema, quando ele reclama que o MySQL não conseguiu entender o que foi solicitado.
  20. Quando eu comecei a mexer com o PHP em 2020, eu não sabia o que era variável global, a minha saída foi usar uma tabela no MySQL chamada tbsupervariavel. Estudando o MVC em 2024, comecei a usar o $_SESSION, essa variável sobrevive até você fechar o navegador. Isso é mais do que satisfatório para o projeto. O problema é que restaram quatro valores e que precisava ir além de uma sessão do navegador. Como o número de campos é pequeno, pensei em usar a tabela tbusuario. Mas eu lembrei que existe mais um cantinho no PHP, é o famoso Config.php, onde é definido as constantes. Tentei alterar o valor das constantes através de um <form>, mas só foi perda de tempo. Não dá para alterar o arquivo Config.php se ele está sempre aberto, vou ter que alterar na unha. Os meus códigos ficaram assim: Arquivo Modelos / Config.php <?php if($_SERVER['SERVER_NAME']=='astudy.net') { defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT']); $dbname="Diario"; $user="Root"; $password="12345678"; } else { defined('PROJETO') || define('PROJETO',$_SERVER['DOCUMENT_ROOT'].'/Frank/'); $dbname="diario"; $user="root"; $password=""; } defined('CONTROLES') || define('CONTROLES',PROJETO.'/Controles/'); defined('MODELOS') || define('MODELO',PROJETO.'/Modelos/'); defined('VISOES') || define('VISOES',PROJETO.'/Visoes/'); defined('HOST') || define('HOST','localhost'); defined('DBNAME') || define('DBNAME',$dbname); defined('USER') || define('USER',$user); defined('PASSWORD') || define('PASSWORD',$password); defined('lctoBaixaEstoque') || define('lctoBaixaEstoque',11301); defined('lctoAcertoMais') || define('lctoAcertoMais',11658); defined('lctoAcertoMenos') || define('lctoAcertoMenos',11659); defined('diaAcerto') || define('diaAcerto','2024-03-31'); Arquivo Controles / Controle.php <?php session_start(); require_once $_SERVER['DOCUMENT_ROOT'].'/Frank/Modelos/Config.php'; class Controle { public $Conexao; public function __construct() { $this->Conexao = new Conexao(); } public function outros() { $baixa=lctoBaixaEstoque; $menos=lctoAcertoMenos; $mais=lctoAcertoMais; $diaAcerto=diaAcerto; $valorBaixa=$this->Conexao->select("valor from tbdiario where lcto=$baixa")[0]->valor; $valorMenos=$this->Conexao->select("valor from tbdiario where lcto=$menos")[0]->valor; $valorMais=$this->Conexao->select("valor from tbdiario where lcto=$mais")[0]->valor; return $this->view('Outros',['baixa'=>$baixa,'valorBaixa'=>$valorBaixa, 'menos'=>$menos,'valorMenos'=>$valorMenos,'mais'=>$mais, 'valorMais'=>$valorMais,'diaAcerto'=>$diaAcerto]); } Arquivo Visoes / Outros.php <?php include VISOES . 'Menu.php'; ?> <script>btmenu.innerHTML='Outros'</script> <table class="table table-sriped linha"> <tr><td><a href=?ControleEstoque.baixarestoque>Baixar Estoque</a> <tr><td><a href=?ControleDiario.tbw>Criar tbw</a> <tr><td><a href=?ControleEstoque.descontinuar>Descontinuar Produto</a> <tr><td><a href=?ControleEstoque.diferencaEstoque>Diferença no Estoque</a> <tr><td><a href=?ControleEstoque.entraproduto>Entrada de Produtos</a> <tr><td><a href=?Controle.megasena.php>Mega-Sena</a> <tr><td><a href=?Controle.painel>Painel SQL</a> <tr><td>$_SESSION['apuracao']->apuracao<td> <?php echo isset($_SESSION['apuracao']) ? $_SESSION['apuracao']->apuracao : 'Não definido';?> <tr><td>$_SESSION['codp']<td> <?php echo isset($_SESSION['codp']) ? $_SESSION['codp'] : 'Não definido';?> <tr><td>$_SESSION['codprod']<td> <?php echo isset($_SESSION['codprod']) ? $_SESSION['codprod'] : 'Não definido';?> <tr><td>$_SESSION['criterio']<td> <?php echo isset($_SESSION['criterio']) ? $_SESSION['criterio'] : 'Não definido';?> <tr><td>$_SESSION['dia']<td> <?php echo isset($_SESSION['dia']) ? $_SESSION['dia'] : 'Não definido';?> <tr><td>$_SESSION['docto']<td> <?php echo isset($_SESSION['docto']) ? $_SESSION['docto'] : 'Não definido';?> <tr><td>$_SESSION['endereco']<td> <?php echo isset($_SESSION['endereco']) ? $_SESSION['endereco'] : 'Não definido';?> <tr><td>$_SESSION['id']<td><?=$_SESSION['id']?> <tr><td>$_SESSION['lcto']<td> <?php echo isset($_SESSION['lcto']) ? $_SESSION['lcto'] : 'Não definido';?> <tr><td>$_SESSION['pessoa']<td> <?php echo isset($_SESSION['pessoa']) ? $_SESSION['pessoa'] : 'Não definido';?> <tr><td>Define:lctoBaixaEstoque<td><?=$baixa?><td class=text-end><?=dec($valorBaixa)?> <tr><td>Define:lctoAcertoMais<td><?=$mais?><td class=text-end><?=dec($valorMais)?> <tr><td>Define:lctoAcertoMenos<td><?=$menos?><td class=text-end><?=dec($valorMenos)?> <tr><td>Define:diaAcerto<td><?=$diaAcerto?><td>
  21. Eu tenho 12 tabelas no MySQL, onze delas têm o prefixo tb (tbconta, tbdiario, tbproduto) , isso é coisa que herdei do tempo que usei o Microsoft Access. Mas em 2022 comecei a estudar o Laravel, e ele acrescentou uma nova tabela chamada Users. Agora, eu pedi para o MysQL mudar o nome da tabela Users para tbusuario, isso é bem fácil. O problema é quando o Laravel reclama que não está conseguindo achar a tabela users. Para resolver o problema, eu fui no Model User, e acrescentei a linha protected $table="tbusuario"; e tudo voltou a funcionar como se nada tivesse acontecido. O Model do Laravel é sofisticado, ele permite associar um nome diferente da tabela para o projeto todo. Eu tenho 12 Model no Laravel, um para cada tabela. Já no meu projeto em MVC, eu não tenho nenhum Model associado à tabela do MySQL. Só tenho o arquivo Conexao.php, onde defini funções genéricas assim public function select($sql) {return json_decode(json_encode($this->instancia()->query("select $sql"))); }. Não senti necessidade de usar um Model para cada tabela.
  22. Testei o argumento true no json_decode, mas o Laravel não manda o json de jeito nenhum. Logo, não há como executar dd($array->teste), ele reclama Attempt to read property "apuracao" on array. Você conseguiu executar o código na sua máquina?
  23. Eu fiz assim: <?php $headers=array('Authorization: c5c8fef6610893b3d52d6442d73b7814a6e35ee54624e44bf5712b88bdcdff9e', 'Accept: application/json' ); $ch = curl_init('https://ssw.inf.br/api/consultaGenerica/consultaPrazo?idCepDestinatario=80000000&idCepRemetente=80000000'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); echo $response; // Mostra o conteúdo da página Mas não deu certo. O máximo que eu consegui foi testar o endereço, onde obtive essa mensagem: {"erro":true,"mensagem":"Obrigatorio informar o token no Header "Authorization""}
  24. Hoje, a Gemini me ensinou como usar as rotas no Laravel. Ela ofereceu várias sugestões, a que menos assustou foi o uso do session( ). A sintaxe no arquivo blade é assim: <a hef={{route('apuracao',['apuracao'=>$apuracao]}}>{{$mes}}</a> mas eu recebi a mensagem de erro. A Gemini disse que existem vários fatores que podem explicar resultados inesperados, desde o erro de sintaxe até a configuração do servidor. Isso não ajuda muito, eu usei o velho motor de busca do Google, e por sorte achei um tema mais ou menos semelhante. Eu fui até o arquivo web.php no diretório routes, e encontrei esse pedaço de código: Route::get('apuracao',[App\Http\Controllers\DiarioController::class,'apuracao']) Aqui eu defini uma rota e como chegar nela. O meu erro é que esqueci de batiza-lo, assim: Route::get('apuracao',[App\Http\Controllers\DiarioController::class,'apuracao'])->name('apuracao'); Pode um negócio desses?
×
×
  • Criar Novo...