Ir para conteúdo
Fórum Script Brasil

Frank K Hosaka

Membros
  • Total de itens

    1.206
  • Registro em

  • Última visita

Tudo que Frank K Hosaka postou

  1. Eu tenho uma collection chamada $tarifa e outra chamada $venda, ambos usam as mesmas datas. O problema é colocar lado a lado, dentro de uma tabela. No PHP, eu uso a chave do array da $tarifa para chamar o valor da $venda. Já o Laravel usa a tecnologia dos collections, e eu não tenho a menor ideia de como trabalhar com isso. Assim, eu apelei para o PHP, a minha única dúvida era saber se o PHP é capaz de trabalhar com as collections do Laravel. O certo é estudar o Laravel, mas esse é um dos casos que é bem mais rápido apelar para o PHP: app > Http > Controllers > DiarioController <?php // lista parcial public function mercado(Request $request){ $dataInicial='2024-01-01'; $dataFinal='2024-01-31'; $tarifas=tbdiario::where('contad',407)->where('hist','like','Mercado%') ->whereBetween('dia',[$dataInicial,$dataFinal])->get(); $venda=tbdiario::where('contac',304)->where('hist','like','Mercado%') ->whereBetween('dia',[$dataInicial,$dataFinal])->get(); $somaTarifa=$tarifas->sum('valor'); $somaVenda=$venda->sum('valor'); return view('mercado',compact('tarifas','venda','somaTarifa','somaVenda'));} resources > views >mercado.blade.php @include('menu') <script>btmenu.innerHTML='Mercado Pago Janeiro 2024'</script> <table class='table table-striped linha'><tr><th>Dia<th class=text-end>Tarifa<th class=text-end>Venda @foreach($tarifas as $key=>$tarifa) @php $valorVenda=$venda->where('dia',$tarifa->dia)->value('valor'); @endphp <tr><td>{{date('d/m/y',strtotime($tarifa->dia))}} <td class=text-end nowrap >{{dec($tarifa->valor)}} <td class=text-end>{{dec($valorVenda)}} @endforeach <tr><th>Total<th class=text-end>{{dec($somaTarifa)}} <th class=text-end>{{dec($somaVenda)}} </table> Pensando um pouco mais, eu decidi trabalhar com a collection como se fosse um array. E a ideia deu certo, não vou precisar do marcador @php no blade: resources>views>mercado.blade.php @include('menu') <script>btmenu.innerHTML='Mercado Pago Janeiro 2024'</script> <table class='table table-striped linha'><tr><th>Dia<th class=text-end>Tarifa<th class=text-end>Venda @foreach($tarifas as $key=>$tarifa) <tr><td>{{date('d/m/y',strtotime($tarifa->dia))}} <td class=text-end nowrap >{{dec($tarifa->valor)}} <td class=text-end>{{dec($venda[$key]->valor)}} @endforeach <tr><th>Total<th class=text-end>{{dec($somaTarifa)}} <th class=text-end>{{dec($somaVenda)}} </table>
  2. O meu aluguel com a hospedagem de site vai terminar em 24 de fevereiro de 2024. Hoje eu decidi pegar um servidor VPS no Hostinger. Ainda estou me familiarizando com as novas ferramentas. Para testar o VPS, eu criei um subdominio assim vps.astudy.net e apontei para o IP do VPS; suponho que amanhã o subdomínio vai estar disponível e pegar o index.php que eu inventei na pasta htdoc. Ou eu estou fazendo alguma besteira?
  3. É possível usar o método GET para chamar um formulário, e usar o método POST para submeter o formulário. O único problema é atualizar o cabeçalho do navegador, e o único meio é usando o comando action do <form> assim: arquivo Index.php <?php class Teste { public function __construct(){ if(isset($_GET)){ $get=$_GET; switch(key($get)){ case 'get':echo "método get";break;}} if(isset($_POST)){ $post=$_POST; switch(key($post)){ case 'post':echo "método post";break;}}}} $teste=new Teste(); ?> <table> <tr><td><form><input type=submit value=MetodoGet name=get></form> <tr><td><form action="index.php" method=post><input type=submit value=MetodoPost name=post></form> </table>
  4. Faz uma semana que estou com problema numa classe chamada Pessoa, basicamente ele faz uma lista ou procura alguém. Eu não entendi porque a rotina de procurar não funcionava. Tenho uma outra classe chamada Produto, e ele funciona. Não consegui entender por que a classe Produto funciona e a classe Pessoa não funciona. Fazendo um rascunho, eu descobri o problema: <?php class Teste { public function __construct(){ if(isset($_GET)){ $get=$_GET; switch(key($get)){ case 'get':echo "método get";break;}} if(isset($_POST)){ $post=$_POST; switch(key($post)){ case 'post':echo "método post";break;}}}} $teste=new Teste(); ?> <table> <tr><td><form><input type=submit value=MetodoGet name=get></form> <tr><td><form method=post><input type=submit value=MetodoPost name=post></form> </table> Graças a esse código, eu vi que usei o método post tanto para fazer a listagem inicial dos produtos bem como a procura de um produto. Esse não foi o caso da classe Pessoas, eu usei o método get para fazer a listagem e o método post para procurar alguém. Para corrigir o problema, eu só mudei o método da procura para get, dentro da classe Pessoas, bem como o <form> correspondente.
  5. Eu não conhecia o objeto literal no JavaScript, testei e funcionou, menos na hora de interpolar os textos. Hoje eu finalmente descobri como funciona a interpolação. A interpolação no JavaScript só funciona no meu notebook se eu usar aspas craseadas, e a interpolação no PHP só funciona se eu usar aspas duplas, assim: <script> programador = {"nome": "Fábio Akita","linguagem": "Ruby"} alert(`Olá, ${programador.nome}`) </script> <?php $programador=json_decode('{"nome":"Fábio Akita","linguagem":"Ruby"}'); echo "Olá, $programador->nome"; Para calcular o dia da semana em português, a minha sugestão é: <?php $week=['Mon','Thu','Wed','Tue','Fri','Sat','Sun']; $semana=['segunda','terça','quarta','quinta','sexta','sábado','domingo']; echo "hoje é " . $semana[array_search(date("D"),$week)];
  6. A melhor forma de controlar um <form> é usando <input required>, a <form> não será submetida se o <input required> não for preenchida. O problema é quando tem um <input type=hidden>. Consultando o Bard, ele sugeriu usar a função preventDefault( ) no JavaScript, só que ele não funcionou. Depois de pesquisar o Google, tive a sorte de encontrar uma dica que funciona: <form onsubmit="return false">. Adaptei no meu código, e ele ficou assim: arquivo ProdutoIncluir.php <?php include VISAO . "/Menu.php"; ?> <script> btmenu.innerHTML='Produto' function verificaCodp(){ if(codp.value==''){ alert('Favor selecionar o fornecedor')} else {frmProd.submit()}} </script> <table class='table table-striped'> <form id=frmProd onsubmit='verificaCodp();return false'> <input type=hidden name=incluir value=incluir> <tr><td>Codigo<td><?=$prod->codprod?><input type=hidden name=codprod value=<?=$prod->codprod?>> <tr><td>Produto<td><?=$prod->prod?><input type=hidden name=prod value=<?=$prod->prod?>> <tr><td>Custo<td><?=$prod->custo?> <tr><td>Margem<td><?=$prod->marg?> <tr><td>Venda<td><?=$prod->custo?> <tr><td>Codigo de Barra<td><?=$prod->codbar?> <tr><td>NCM<td><?=$prod->cf?> <tr><td>Quantidade<td><input name=qt required> <tr><td>CustoTotal<td><input name=custototal required> <tr><td>Lçto<td><?=$lcto?><input type=hidden name=lcto value=<?=$lcto?>> <tr><td>Pessoa<td><a href=ControleDiario.php?pessoa><?=$pessoa?></a> <tr><td><td><input type=submit> <input type=hidden name=codp id=codp value=<?=$codp?>> </form> </table>
  7. <?php // ver https://www.correios.com.br/atendimento/developers/apicoleta if(isset($_GET['id'])){ $id=$_GET['id']; echo "<iframe src=http://www.linkcorreios.com.br/?id=$id width=700px height=500px></iframe>";} ?> <form> Rastreando o objeto <input type=submit name=id value="PO117284423BR"> </form>
  8. Depois de três anos estudando PHP, a primeira reação de quem vê o MVC é entrar em pânico. O PHP é bem abstrato, em três anos só aprendi 2% do que ele é capaz. E agora estou começando a engatinhar no MVC (ou POO PHP), e hoje eu consegui criar dois controladores, cada um cuidando de uma tabela: arquivo Index.php <?php session_start(); class ControladorPessoa { public function __construct(){ if(isset($_GET['proxPessoa'])){$_SESSION['vetorPessoa']++;}} public function consulta(){ $_SESSION['vetorPessoa']=0; $conexao=new Conexao(); return $conexao->consulta("tbpessoa");}} class ControladorProduto { public function __construct(){ if(isset($_GET['proxProd'])){$_SESSION['vetorProduto']++;}} public function consulta(){ $_SESSION['vetorProduto']=0; $conexao=new Conexao(); return $conexao->consulta("tbprod");}} class Conexao { public function consulta($tabela){ $pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); $stmt=$pdo->query("select * from $tabela"); return $stmt->fetchAll(PDO::FETCH_OBJ);}} $controlePessoa=new ControladorPessoa(); $controleProduto=new ControladorProduto(); if(!isset($_SESSION['pessoas'])){$_SESSION['pessoas']=$controlePessoa->consulta();} if(!isset($_SESSION['produtos'])){$_SESSION['produtos']=$controleProduto->consulta();} $pessoas=$_SESSION['pessoas']; $produtos=$_SESSION['produtos']; $vetorPessoa=$_SESSION['vetorPessoa']; $vetorProduto=$_SESSION['vetorProduto']; require 'Consulta.php'; arquivo Consulta.php <body style=margin-left:400px> <h4>Amostra da tabela Pessoa:</h4> <?=$pessoas[$vetorPessoa]->pessoa?> <form> <input type=submit value="Próxima Pessoa"> <input type=hidden name=proxPessoa value=<?=$vetorPessoa?>> </form> <hr> <h4>Amostra da tabela Produtos:</h4> <?=$produtos[$vetorProduto]->prod?> <form> <input type=submit value="Próximo Produto"> <input type=hidden name=proxProd value=<?=$vetorProduto?>> </form> </body>
  9. Ontem eu vi o roteador do meu controlador Diario. Aquilo ficou feio de danar. Não consegui encontrar no Bard e no Google nada que pudesse melhorar a maquiagem do roteador. Hoje eu acordei com a ideia de esconder o roteador dentro da classe. O problema é como fazer a classe enxergar as solicitações do navegador. A minha solução foi esconder o roteador dentro da função __construct(). O meu teste deu certo: arquivo Index.php <?php class Controlador { private $mensagem; public function __construct(){ if(isset($_GET)){ $roteadorGet=$_GET; switch(key($roteadorGet)){ case 'escrever': $this->mensagem="olá mundo"; break; case 'apagar': $this->mensagem="";break;} $mensagem=$this->mensagem; require 'Teste.php';}}} $controlador=new Controlador(); ?> arquivo Teste.php <form> <table> <tr><td><input type=submit name=escrever value=Escrever> <tr><td><input type=submit name=apagar value=Apagar> </table> </form> <div><?=$mensagem?></div>
  10. views é um recurso bem avançado do MySQL, eu consegui montar alguns em 2020, hoje eu não faço a menor ideia de como montar um view no MySQL. Em 2023, eu hospedei o meu banco de dados no Hostinger, só que as views não funcionaram. Então, eu usei o MySQL Workbench do meu notebook, e copiei a estrutura da view, mas eu tive que eliminar as linhas entre a palavra CREATE e VIEW, para criar a view no Hostinger. Ou seja, a view do Hostinger não é a mesma view que eu tenho no notebook. Para atualizar o meu banco de dados no notebook, eu peço para o Hostinger fazer a exportação mas sem os views. Hoje, no entanto, eu cochilei e esqueci de desmarcar as views na hora de exportar. Na hora que importei, o banco de dados do meu notebook ficou inoperante. Para torná-lo operante, eu precisei eliminar todas as views que foram importadas. O problema é que o Hostinger não trabalha com MySQL Workbench e sim o phpMyAdmin, e consultei o Google como ver a estrutura de um view no phpMyAdmin, mas eu só consegui a parte inicial da estrutura. Eu precisava da estrutura inteira. Tentei prosseguir com a pesquisa, mas a minha conexão com a internet caiu. Então, eu lembrei do VS Code e pedi para ele abrir o arquivo que havia importado do Hostinger, e encontrei a estrutura das views. Tudo o que eu precisava fazer é eliminar as instruções entre as palavras CREATE e VIEW. Pedi para o MySQL importar novamente, e agora deu tudo certo. Ao invés de criar um view, eu uso o PHP que é muito mais fácil de entender. A gramática do PHP é menos abstrata que a gramática MySQL. Em compensação, um view pode poupar centenas de códigos do PHP.
  11. Eu levei cinco horas para montar o código a seguir. Eu recebi várias mensagens de erro, muitos eram familiares mas não sabia do que se tratava. O mais enigmático é que eu não podia usar a variável $_SESSION junto com o motor de banco de dados. Depois de várias tentativas e erros, acabei descobrindo que todos os erros eram gramaticais, usei o recurso do PHP aonde não devia. O grande problema do MVC é criar um controlador para cada tabela do banco de dados. Isso não é fácil, principalmente quando eu preciso de uma informação numa tabela que está disponível em outra tabela. Para criar uma ponte entre os controladores, eu usei a variável $_SESSION, assim: <?php session_start(); class Produto { public function incluir() { $lcto=$_SESSION['lcto']; $codprod=1;$qt=1;$subtotal=1; $pdo=new PDO("mysql:host=localhost;dbname=laravel","root",""); $pdo->query("insert into tbhistprod (lcto,codprod,qt,subtotal) values ($lcto,$codprod,$qt,$subtotal)");}} class Diario { public function incluir() { $contad=123;$contac=121;$valor=10;$historico='Compra de um repolho na quitanda'; $pdo=new PDO("mysql:host=localhost;dbname=laravel","root",""); $pdo->query("insert into tbdiario (contad,contac,valor,historico) values ($contad,$contac,$valor,'$historico')"); $_SESSION['lcto']=$pdo->lastInsertId(); $produto=new Produto(); $produto->incluir();}} $diario=new Diario(); $diario->incluir(); Olhando o código, o mais sensato era colocar o número do lançamento como parâmetro da função e não como variável global $_SESSION. O problema são os formulários, um vai pegar as contas, o outro vai pegar os produtos, e depois de várias submissões, tudo o que estava no caminho se perde no Vale das Sombras. Outra coisa bacana que aprendi com o MVC é a barra de endereço do navegador. Lá aparece o nome do controlador. No caso de uma submissão de um formulário, o PHP vai carregar o controlador que estiver na barra de endereço, assim decidi não usar a propriedade action do <form>, mas sim preparar o controlador para receber a submissão.
  12. Estava pensando em utilizar a variável $_SESSION no meu projeto MVC Orçamento. Para saber como ele funciona, eu criei esse código Index.php na pasta Astudy: <meta name="viewport" content="width-device-width, initial-scale=1.0"> <?php session_start(); if(isset($_SESSION['time'])){ echo "O melhor time do mundo é o " . $_SESSION['time'];} if(isset($_GET['time'])){ $_SESSION['time']=$_GET['time']; header("location:Index.php");} ?> <body style='margin:0 auto'> <p>Qual o melhor time de todo o universo?</p> <form> <p><a href="?time=São Paulo">São Paulo</a><p> <p><a href="?time=Palmeiras">Palmeiras</a><p> <p><a href="?time=Corinthians">Corinthians</a> </form> Para testar esse programa, usei o meu notebook, colocando no navegador: localhost/astudy, e escolhi São Paulo. No celular, eu digitei 192.168.0.10/astudy. Apesar do programa ser o mesmo, a escolha que eu faço no notebook não afeta a escolha do celular e vice versa. Ou seja, a variável $_SESSION é global mas ele está vinculado a cada usuário e não ao código. Assim, eu posso usar a variável $_SESSION sem me preocupar com a escolha de outros usuários. Esse é um recurso bacana, mas ele não funciona para o banco de dados. O PHP não inventa um banco de dados para cada usuário. Nesse caso, eu preciso estudar muito para evitar que dois ou mais usuários tentem editar o mesmo registro ao mesmo tempo, eu ainda não tenho a menor ideia de como fazer isso.
  13. Por outro lado, se você persiste em trabalhar com cinco campos numéricos, a minha sugestão é a mesma, o de usar o recurso do array do PHP para calcular a frequências dos números envolvidos: <?php function frequencia($frequencia,$elemento){ $style="style=text-align:right"; if($frequencia[$elemento]==2){$style="style=text-align:right;color:green";} if($frequencia[$elemento]==3){$style="style=text-align:right;color:red";} echo "<td $style>$elemento |";} $pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); $stmt=$pdo->query("drop table if exists vetores"); $stmt=$pdo->query("create table vetores (id int not null auto_increment, re1 int default null, re2 int default null, re3 int default null, re4 int default null, re5 int default null, primary key(id)) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci"); $arrays=[[123,122,121,111,132],[122,22,221,211,232],[12,13,132,11,15],[123,32,33,36,123]]; foreach($arrays as $array){ $re1=$array[0]; $re2=$array[1]; $re3=$array[2]; $re4=$array[3]; $re5=$array[4]; $pdo->query("insert into vetores (re1,re2,re3,re4,re5) values ($re1,$re2,$re3,$re4,$re5)");} $stmt=$pdo->query("select * from vetores"); $todos=$stmt->fetchAll(PDO::FETCH_OBJ); $umVetor=[]; foreach($todos as $cada){ $umVetor=array_merge($umVetor,[$cada->re1,$cada->re2,$cada->re3,$cada->re4,$cada->re5]);} $frequencia=array_count_values($umVetor); ?> <table style=margin-left:400px><th>id |<th>re1 |<th>re2 |<th>re3 |<th>re4 |<th>re5 | <?php foreach($todos as $cada): ?> <tr><td style=text-align:right><?=$cada->id?> | <?php frequencia($frequencia,$cada->re1); frequencia($frequencia,$cada->re2); frequencia($frequencia,$cada->re3); frequencia($frequencia,$cada->re4); frequencia($frequencia,$cada->re5); endforeach;
  14. <?php $pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); $stmt=$pdo->query("drop table if exists vetores"); $stmt=$pdo->query("create table vetores (id int not null auto_increment, vetor json default null, primary key(id)) engine=InnoDB default charset=utf8mb4 collate=utf8mb4_0900_ai_ci"); $arrays=[[123,122,121,111,132],[122,22,221,211,232],[12,13,132,11,15],[123,32,33,36,123]]; foreach($arrays as $array){ $json=json_encode($array); $pdo->query("insert into vetores (vetor) values ('$json')");} $stmt=$pdo->query("select * from vetores"); $todos=$stmt->fetchAll(PDO::FETCH_OBJ); $umVetor=[]; foreach($todos as $cada){ $umVetor=array_merge($umVetor,json_decode($cada->vetor));} $frequencia=array_count_values($umVetor); ?> <table style=margin-left:400px><th>id |<th>re1 |<th>re2 |<th>re3 |<th>re4 |<th>re5 | <?php foreach($todos as $cada): ?> <tr><td style=text-align:right><?=$cada->id?> | <?php $vetor=json_decode($cada->vetor); foreach($vetor as $elemento): $style="style=text-align:right"; if($frequencia[$elemento]==2){$style="style=text-align:right;color:green";} if($frequencia[$elemento]==3){$style="style=text-align:right;color:red";} ?> <td <?=$style?>><?=$elemento?> | <?php endforeach; endforeach; ?> Ao invés de trabalhar com cinco campos re1 ... re5, a minha sugestão é trabalhar com apenas um campo tipo texto para armazenar os cinco números na forma de array.
  15. Tudo funciona quando as classes estão agrupadas no Index.php, mas na hora de separar por pastas e na hora de trabalhar com um serviço de banco de dados dentro de uma classe que foi guardado dentro da variável global $_SESSION, a mensagem que eu recebo é esse: Fatal error: Uncaught Error: The script tried to call a method on an incomplete object. Please ensure that the class definition "Classe" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide an autoloader to load the class definition in C:\wamp64\www\Astudy\Controles\Classe.php on line 10 arquivo Controles > bd.php <?php class bd { public function dados () { $pdo=new PDO("mysql:host=localhost;dbname=diario","root",""); $stmt=$pdo->query("select * from tbprod limit 2"); return $stmt->fetchAll(PDO::FETCH_OBJ);}} arquivo Controles > Classe.php <?php require __DIR__ . '/Subclasse.php'; class Classe extends SubClasse { private $variavel; public function get() {return $this->variavel;} public function set($valor) {$this->variavel = $valor;}} if(!isset($_SESSION['objeto'])){$_SESSION['objeto'] = new Classe();} if (isset($_GET['valor'])) {$_SESSION['objeto']->set($_GET['valor']);} if (isset($_GET['obter'])) {echo $_SESSION['objeto']->get();} if (isset($_GET['bd'])){var_dump($_SESSION['objeto']->bd());}?> <form><input name=valor onchange=submit()></form> <form><input type=submit name=obter value=Obter></form> <form><input type=submit name=bd value=bd></form> arquivo Controles > Subclasse.php <?php require __DIR__ .'/bd.php'; class Subclasse { public function bd(){ $conexao=new bd(); return $conexao->dados();}} arquivo Index.php <?php session_start(); require __DIR__ . '/Controles/Classe.php'; $_SESSION['Diario']=new Classe();
  16. Em 2020 eu criei a tabela tbsupervariavel para poder salvar alguns valores no meio do caminho para utilizar lá na frente. Aqui em 2023 estou batendo a cabeça na parede para estudar o MVC, mais conhecido como "programação orientada a objetos", mas não vejo como eliminar a tbsupervariavel. Sente o meu drama: <?php session_start(); class Classe { private $variavel; public function get() {return $this->variavel;} public function set($valor) {$this->variavel = $valor;}} if(!isset($_SESSION['objeto'])){ $_SESSION['objeto'] = new Classe();} if (isset($_GET['valor'])) {$_SESSION['objeto']->set($_GET['valor']);} if (isset($_GET['obter'])) {echo $_SESSION['objeto']->get();} ?> <form action="" method="get"> <input name="valor" onchange="this.form.submit()"> </form> <form action="" method="get"> <input type="submit" name="obter" value="Obter"> </form> Alguém sabe como fazer esse código funcionar sem usar a gambiarra da $_SESSION?
  17. Hoje eu criei a classe OrcamentoControle como uma extensão da classe ProdutoControle, assim eu consegui usar a função procurar( ) do ProdutoControle dentro da classe OrçamentoControle. O problema é que eu só consegui usar só uma vez. Na segunda vez, o PHP reclamou que o ProdutoControle não tinha conexão. Para continuar com o serviço, eu tive que fazer uma bela gambiarra, ao invés de iniciar a conexão com o famoso __construct( ), eu defini a conexão dentro da função da classe ProdutoControle: Arquivo Astudy > Controles > ProdutoControle.php <?php require_once $_SERVER['DOCUMENT_ROOT'] . "/Astudy/Modelos/Conexao.php"; class ProdutoControle{ private $pdo; public function procurar(){ $this->pdo=Conexao::instancia(); $stmt=$this->pdo->query("select * from tbprod limit 10"); $produtos=$stmt->fetchAll(PDO::FETCH_OBJ); require $_SERVER['DOCUMENT_ROOT'] . "/Astudy/Visoes/Produtos.php"; exit; } } Arquivo Astudy > Controles > OrcamentoControle.php <?php require_once $_SERVER['DOCUMENT_ROOT'] . "/Astudy/Controles/ProdutoControle.php"; require_once $_SERVER['DOCUMENT_ROOT'] . "/Astudy/Modelos/Conexao.php"; class OrcamentoControle extends ProdutoControle { private $pdo; public function __construct(){ $this->pdo=Conexao::instancia();} public function inicio(){ $pedido=1; if(isset($_GET['codprod']) && !isset($_GET['qt'])){ $prod['codprod']=$_GET['codprod']; $prod['prod']=$_GET['prod']; $prod['custo']=$_GET['custo'];} $stmt=$this->pdo->query("select * from tbhistped join tbprod on tbhistped.codprod = tbprod.codprod where ped=$pedido"); $itens=$stmt->fetchAll(PDO::FETCH_OBJ); require $_SERVER['DOCUMENT_ROOT']."/Astudy/Visoes/Orcamento.php";exit;} public function incluir(){ $ped=1; $codprod=$_GET['codprod']; $qt=$_GET['qt']; $subtotal=$codprod*$qt; $this->pdo->query("insert into tbhistped (ped,codprod,qt,subtotal) values ($ped,$codprod,$qt,$subtotal)"); $this->inicio();}} $controle=new OrcamentoControle(); if(isset($_GET)){ if(key($_GET)=='produto'){$controle->procurar();} if(key($_GET)=='codprod'){$controle->inicio();} if(key($_GET)=='qt'){$controle->incluir();} }
  18. Eu tenho pavor do VBA, principalmente no Excel, sempre recebo mensagens estranhas e a tela de ajuda é de amargar, mas para resolver esse tipo de problema, eu uso o gravador de macro. Eu faço uma busca manual, encontro o que eu preciso, e depois estudo a macro que o Excel criou. O meu ficou assim: Sub Macro1() Dim val As String val = InputBox("O que procura?") Cells.Find(What:=val, After:=ActiveCell, LookIn:=xlFormulas2, LookAt _ :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _ False, SearchFormat:=False).Activate End Sub
  19. Não consegui executar o código do ikkinet, eu fiz as seguintes modificações: arquivo routes>web.php <?php use Illuminate\Support\Facades\Route; Route::get('/',[App\Http\Controllers\IndexController::class,'index']); arquivo app>Http>Controllers>IndexController.php <?php namespace App\Http\Controllers; class IndexController extends Controller { public function index(){ // tirei :view da versão original $data['nome'] = 'Pedro'; $data['idade'] = 37; $data['valor'] = 25.2; $data['notas'] = ['q1' => 8,'q2' => 7,'q3' => 9,'q4' => 10]; return view('nome_do_arquivo_da_view',compact('data'));}} // tirei ->with($data) do original arquivo resources > views > nome_do_arquivo_da_view.blade.php <div class="row"> <label>Nome</label> <p>{{ $data['nome'] }}</p> </div> <div class="row"> <label>Idade</label> <p>{{ $data['idade'] }}</p> </div> <div class="row"> <label>Valor</label> <p>{{ $data['valor'] }}</p> </div> <div class="row"> <label>Media das notas dos bimestres</label> <p>{{ ($data['notas']['q1']+$data['notas']['q2']+ $data['notas']['q3']+$data['notas']['q4'])/4 }}</p> </div> <!-- a minha versão do laravel é básica, eu nem consegui instalar o Breezer. Ele não permite usar a chave de um array como se fosse uma variável. --> Desconfio que o ikkinet tem uma versão bem mais poderosa do Laravel ou ele está bebemorando 2024 muito antes das datas previstas. Seja como for, fiz um teste, eu tirei compact('data') no código do controller, e o Laravel reclamou que tem um monte de variável indefinida e isso não faz o menor sentido. O que o Laravel fez com a classe IndexController onde foi definida a variável $data? Isso é um bom exemplo de que eu fiz a coisa errada. O Laravel não ensina ninguém a criar um MVC, pois o Laravel é um MVC, mas um MVC bem obscuro. No MVC a gente chama um arquivo para mostrar no navegador, já o Laravel "renderiza", ou seja, ele mostra o arquivo no navegador e some com o controlador que chamou o arquivo. O nome disso é "mágica"!
  20. Finalmente terminei o rascunho (ele só faz o básico, ele não contempla nenhum controle dos que já foram selecionados e nem a quantidade necessária de cada serviço, e como ele trabalha com data precisa definir o local, coisa que também não fiz). Espero que você goste: Mysql CREATE TABLE `tb_escaladiaria` ( `id` int NOT NULL AUTO_INCREMENT, `data` date DEFAULT NULL, `id_servidor` int DEFAULT NULL, `id_servico` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CREATE TABLE `tb_servicos` ( `id` int NOT NULL AUTO_INCREMENT, `descricao` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=innoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci CREATE TABLE `tb_servidores` ( `id` int NOT NULL AUTO_INCREMENT, `nome` varchar(45) DEFAULT NULL, `id_servico` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci arquivo Index.php <body style='width:1200px;margin:0 auto;margin-top:50px'> <?php $pdo=new PDO('mysql:host=localhost;dbname=diario','root',''); $stmt=$pdo->query("select * from tb_escaladiaria join tb_servidores on id_servidor = tb_servidores.id join tb_servicos on tb_servidores.id_servico = tb_servicos.id"); $escalas=$stmt->fetchAll(PDO::FETCH_OBJ); if(isset($_GET['servidor'])){ $dia=date('Y-m-d'); $id_servidor=$_GET['servidor']; $id_servico=$_GET['idServico']; $stmt=$pdo->query("insert into tb_escaladiaria (data,id_servidor,id_servico) values('$dia',$id_servidor,$id_servico)"); header("location:index.php?servico=$id_servico");} $stmt=$pdo->query("select * from tb_servicos"); $servicos=$stmt->fetchAll(PDO::FETCH_OBJ); if(isset($_GET['servico'])): $idServico=$_GET['servico']; $stmt=$pdo->query("select descricao from tb_servicos where id=$idServico"); $descricaoServico=$stmt->fetchAll(PDO::FETCH_ASSOC)[0]['descricao']; echo "<input type=submit value='$descricaoServico' onclick=location.replace('index.php')> <i> Clique nesse botão para mudar o serviço</i><p>"; $stmt=$pdo->query("select * from tb_servidores where id_servico=$idServico"); $servidores=$stmt->fetchAll(PDO::FETCH_OBJ); ?> <form> <select name=servidor onchange=submit()> <option>Selecione o colaborador <?php foreach($servidores as $servidor): ?> <option value=<?=$servidor->id?>><?=$servidor->nome?> <?php endforeach; ?> </select> <input type=hidden name=idServico value=<?=$idServico?>> </form> <?php else: ?> <form> <select name=servico id=servico onchange=submit()> <option>Selecione o serviço <?php foreach($servicos as $servico): ?> <option value=<?=$servico->id?>><?=$servico->descricao?> <?php endforeach; ?> </select> </form> <?php endif; ?> <table border=1><th>Data<th>Colaborador<th>Função <?php foreach($escalas as $escala): ?> <tr><td><?=$escala->data?><td><?=$escala->nome?><td><?=$escala->descricao?> <?php endforeach; ?>
  21. A minha ideia é mostrar toda a tabela escaladiaria, onde vão aparecer os servidores e suas funções. Como você não quer escrever na mão essa tabela, vamos precisar de dois formulários. O primeiro vai ter uma combo com os serviços. O segundo vai ter uma combo os servidores que fazem aquele serviço. Assim que ele for selecionado, a tabela escaladiaria será atualizada. A minha ideia é criar uma linha para cada escala assim: 18/12/23 Maria, motorista 18/12/23 João, motorista 18/12/23 Pedro, motorista e não 18/12/23 [Maria, João, Pedro], motorista. Nesse caso, ao invés de um id_servidor (int) teríamos que mudar para ids_servidores (varchar(45)), onde teríamos um array de vários de ids, o que eu acho bem difícil de trabalhar. Aconselho a não fazer isso, a menos que isso seja mais útil para você. Em seguida, um rascunho do que estava fazendo, ele está incompleto, mas preciso abandonar porque tenho que fazer a janta. Boa sorte para você. <?php $pdo=new PDO('mysql:host=localhost;dbname=diario','root',''); $stmt=$pdo->query("select * from tb_escaladiaria join tb_servidores on id_servidor=tb_servidores.id"); $escalas=$stmt->fetchAll(PDO::FETCH_OBJ); if(isset($_GET['servidor'])){ $dia=date('Y-m-d'); $id=$_GET['servidor']; $stmt=$pdo->query("insert into tb_escaladiaria (dia,id_servidor,id_servico) values('$dia','$id',1)");} $stmt=$pdo->query("select * from tb_servicos"); $servicos=$stmt->fetchAll(PDO::FETCH_OBJ); ?> <form> <select name=servico id=servico onchange=submit()> <option>Selecione o serviço <?php foreach($servicos as $servico): ?> <option value=<?=[$servico->id,$servico->descricao]?>><?=$servico->descricao?> <?php endforeach; ?> </select> </form> <?php if(isset($_GET['servico'])): $idServico=$_GET['servico'][0]; $descricaoServico=$_GET['servico'][1]; $stmt=$pdo->query("select * from tb_servidores where id_servico=$idServico"); $servidores=$stmt->fetchAll(PDO::FETCH_OBJ); ?> <form> <select name=servidor onchange=submit()> <option>Selecione o colaborador <?php foreach($servidores as $servidor): ?> <option value=<?=$servidor->id?>><?=$servidor->nome?> <?php endforeach; ?> </select> </form> <?php endif; ?> <table border=1><th>Data<th>Colaborador<th>Função <?php foreach($escalas as $escala): ?> <tr><td><?=$escala->data?><td><?=$escola->nome?><td><?=$escala->funcao?> <?php endforeach; ?>
  22. Eu peço desculpas pelo comentário que realmente não ajudou em nada. O mais importante são as tabelas tb_servidores (id), tb_serviços (id) e tbescaladiaria(id,id_servidor,id_servico), a sua tabela tbescaladiaria não contempla o serviço que será feito pelo servidor. Vamos supor que você precisa de 5 motoristas: Maria, José, João, Mateus e Pedro. Logo, você vai preencher 5 registros na tbescaladiaria. Vamos supor que você pegou a Maria como motorista. Logo, a próxima vez que você selecionar os motoristas disponíveis, devem aparecer apenas José, João, Mateus e Pedro. Nesse caso, precisamos de mais um campo na tb_servidores, assim (id,escalado), e assim podemos fazer uma consulta para popular o formulário dos motoristas que ainda não foram escalados. Outro problema é a tbescaladiaria, como ele vai saber que só podem ser convocados 5 motoristas? Nesse caso, temos mais uma alteração na tbserviços (id, maximo_necessario). Antes de quebrar a cabeça com o formulário, veja se o banco de dados tem informações suficientes para resolver o seu problema. Agora, se a tabela é imexível, aí o escopo é outro. Você tem o escopo do projeto? Escopo é algo do tipo: eu não tenho o privilégio de administrador, não posso mexer na estrutura do banco de dados que é composto dessa tabela (id,nome) e outra tabela (id,descricao), e com essas informações gostaria de saber se é possível fazer um controle de escalas.
  23. Ao invés de servidor, prefiro usar a palavra colaborador. Acho que três tabelas resolvem o problema: colaboradores, serviços e escalas. A tabela colaboradores só tem um id: id=1, Frank. A tabela serviços só tem dois ids: id=1, Faxina; id=2, Programador. Agora a tabela escala tem que ter esses campos: id, data_com_hora_inicio, data_com_hora_final, id_colaborador, id_servico. Na escala de hoje, a tabela ficaria assim: 1,2023-12-18 08:00,2023-12-18 12:00,1,1 2,2023-12-18 13:00,2023-12-18 17:00,1,2 O seu caso é diferente, você trabalha na Câmara Municipal, onde temos vários colaboradores que não têm o que fazer. Nesse caso, a tabela escala ficaria com essa cara: 3,2023-12-18 13:00,2023-12-18 17:00,2,2 4,2023-12-18 13:00,2023-12-18 17:00,3,2 5,2023-12-18 13:00,2023-12-18 17:00,4,2 6,2023-12-18 13:00,2023-12-18 17:00,5,2 Ou seja, são vários colaboradores fazendo o mesmo serviço no mesmo período.
  24. arquivo /Astudy/Index.php <?php require_once __DIR__.'/Modelos/Config.php'; echo DBNAME; echo NovaClasse::teste(); echo "<br>".$config->dec(2); arquivo /Astudy/Modelos/Config.php <?php class Config { public function __Construct(){ defined('HOST') || define('HOST','localhost'); defined('DBNAME') || define('DBNAME','laravel'); defined('USER') || define('USER','root'); defined('PASSWORD') || define('PASSWORD',''); spl_autoload_register(function($Class){ $includeDir = false; $findDir = ['Modelos']; foreach ($findDir as $DirName) { if (!$includeDir && file_exists($this->FindClass($DirName, $Class)) && !is_dir($this->FindClass($DirName, $Class))) { include_once ($this->FindClass($DirName, $Class)); $includeDir = true;}} if (!$includeDir) { die("$Class - Erro interno no servidor ao encontrar dados cruciais de funcionamento!");}}); } public function FindClass($dir,$class) { return ( $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'Astudy' . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $class . '.php');} public function dec($value){ if($value!==null){return number_format($value,2,',','.');}} } // gambiarra $config = new Config(); arquivo /Astudy/Modelos/NovaClasse.php <?php class NovaClasse { public static function teste(){return "<br>isso é um teste!";} }
  25. Hoje eu descobri como funciona o projeto Vagas (GitHub - william-costa/wdev-crud-php-pdo-mysql: CRUD com PHP orientado a objetos, PDO e MySQL feito no canal WDEV), onde o William criou um arquivo chamado formulário, e ele utiliza tanto para cadastrar bem como atualizar o cadastro. Eu não sabia como o formulário era capaz de devolver a resposta do usuário ao programa cadastrar.php ou editar.php. O grande truque é a propriedade action do <form>, o William simplesmente omitiu, ou seja, se o programa cadastrar.php chamar o formulario.php e o usuário apertar o botão enviar, o PHP vai executar novamente o programa cadastrar.php. Desde 2020 eu faço a mesma coisa, mas só nessa semana é que entendi como funciona o PHP. O botão enviar é poderoso para preparar o navegador para receber um novo arquivo HTML, mas não tão poderoso para apagar o último código executado pelo PHP. Essa é a poderosa lei do retorno. O PHP só vai apagar o último código se o HTML pedir. Para testar isso na prática, eu criei o código teste.php: <?php if(isset($_POST['teste'])){ echo "teste concluído";exit;} echo "<form method=post><input type=submit name=teste></form>"; Eu fiz um complicado código no meu projeto para fazer o PHP executar a rotina de quem chamou o formulário, quando, na verdade, a solução do William é bem mais simples. Tudo o que o PHP tem que fazer é esperar a resposta do usuário e executar o código se o usuário responder. Assim, eu tentei ajustar o meu código à simplicidade do William, mas não deu certo. A pergunta é: por que a lei do retorno só funciona no caso do William? A resposta é simples. No caso do William, foi um código PHP puro que chamou o formulário. No meu caso, é uma função de uma classe que chamou o formulário. Ou seja, na hora que o usuário submeter o formulário, o último código executado pelo PHP não é a função que chamou o formulário, mas a classe inteira a que a função pertence. Ou seja, se a classe não estiver preparada, certamente o usuário vai ver uma tela branca e se perguntar porque o PHP não funciona. Mesmo assim, a solução do William (não usar action no <form>) parece funcionar na classe também. Eu pedi para a classe instanciar uma nova classe, e aguardar algum usuário apertar o botão de enviar, e pedi para escrever "olá mundo", e deu certo. Agora, preciso fazer uma gambiarra no formulário para a classe saber se vai cadastrar ou editar um registro. No formulário eu tenho um botão e o texto será definido pela função novo ($btn="novo";) ou pela função edite ($btn="edite";), e dentro do <form> vou criar um <input type=hidden name=retorno value=<?=$btn?>>, e lá na classe instanciada, vou fazer isso: <?php class Diario { ... } $Diario=new Diario() if(isset($_POST['retorno']){ if($_POST['retorno']=="novo"){$Diário->novo();} if($_POST['retorno']=="edite"){$Diário->edite();} } Ideias simples são fáceis de entender, o duro é como usar na prática.
×
×
  • Criar Novo...